<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-960296322531827746</id><updated>2012-01-18T11:28:26.223-08:00</updated><category term='CFL'/><category term='mom cellphone death'/><category term='drm'/><category term='microsoft'/><category term='diamond ring marriage love'/><category term='microsoft marketing vista silverlight'/><category term='siftware development business'/><category term='omega omega3 fish oil depression anxiety'/><category term='C# Serial Port COM names list'/><category term='solar electric'/><category term='stellaris LM3S1607 internal clock SysCtlClockSet'/><category term='science religion mormon athiest'/><category term='FBX Format XNA 3D'/><category term='ruby rails date_select with bracket id'/><category term='work adevice college'/><category term='STM32F103 Reset System Interrupt Hard'/><category term='project management success buy'/><category term='humor'/><title type='text'>Thunderfist</title><subtitle type='html'>I have no idea why anyone would take time to do a blog except to organize thoughts and have the illusion of popularity.  So that must be why I'm doing one.

OK, I'm doing this blog also to post little programming nits that have wasted me a lot of time.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>62</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-8032631369449821162</id><published>2012-01-18T11:28:00.000-08:00</published><updated>2012-01-18T11:28:26.233-08:00</updated><title type='text'>The Real Problem with SOPA</title><content type='html'>So Congress has the SOPA bill before it.  There is a huge online protest to stop it, which is being very effective.&lt;br /&gt;&lt;br /&gt;But next week?  Next month?&lt;br /&gt;&lt;br /&gt;The SOPA and PIPA bills are just the latest in a fairly long line of bills that are designed to control the internet and will not be the last.  Already there is talk about the next bill and how it will be worded better.&lt;br /&gt;&lt;br /&gt;The real problem is not the particular bills.  It is that our elected politicians even feel a need for any bill at all. &lt;br /&gt;&lt;br /&gt;If I remember my Democracy 101, the politicians represent The People.  And I sure don't hear The People clamoring for more internet regulation.&lt;br /&gt;&lt;br /&gt;So what is really up?  We have old congressmen that do not have a clue about the internet.  Some lobbyist comes to them with money and supposed expertise.  The congressmen don't understand the hidden (or not so hidden) agenda of the lobbyists to preserve outdated business models. And they sure don't understand the internet at all.&lt;br /&gt;&lt;br /&gt;The only real hope to come from today's internet protest is that the pile of phone calls from constituents will give the congressmen such a bad taste in their mouth that in the future they will shy away from any bill with the word 'internet' in it.&lt;br /&gt;&lt;br /&gt;And the world will then be a better place. &lt;br /&gt;&lt;br /&gt;TF&lt;br /&gt;&lt;br /&gt;P.S. A recent article &lt;a href="http://www.washingtontimes.com/news/2012/jan/15/congress-logs-most-futile-legislative-year-on-reco/?page=all"&gt;here&lt;/a&gt; has the opinion that the latest session of congress has been the least productive in history.  Meaning they passed the fewest laws.  Since when is passing more laws better?  How about we measure congressional success by how many laws they repeal.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-8032631369449821162?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/8032631369449821162/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=8032631369449821162' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/8032631369449821162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/8032631369449821162'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2012/01/real-problem-with-sopa.html' title='The Real Problem with SOPA'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-5650625655206299825</id><published>2012-01-09T16:08:00.000-08:00</published><updated>2012-01-09T17:31:00.433-08:00</updated><title type='text'>A New Kind of Science - Stephen Wolfram</title><content type='html'>I saw a book called A New Kind of Science online and ordered a used copy.&lt;br /&gt;&lt;br /&gt;Meanwhile, I read it on line while waiting for the hard copy to show up.  When it did the tome was huge.  Yup, I like to buy books by the pound.&lt;br /&gt;&lt;br /&gt;Any ways, The web site for the book is here. &lt;a href="http://www.wolframscience.com/nksonline/toc.html"&gt;A New Kind of Science&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is not just any old book.  There have been several books of science over the centuries that would be called landmark books.  For example &lt;i&gt;Principia Mathematica&lt;/i&gt;, &lt;i&gt;The Origin of the Species&lt;/i&gt; or &lt;i&gt;Godel, Escher, Bach&lt;/i&gt;.  This book is right up there with them.&lt;br /&gt;&lt;br /&gt;(I realize the hyperbole there and am quite serious.)&lt;br /&gt;&lt;br /&gt;Back in Galileo and Newton's time the earthshaking idea they proposed was not just about astronomy, but was the idea that Mathematics could be used to understand and describe the natural world.  Before that Mathematics was considered purely abstract, of the mind.  Newton came up with calculus and linear equations to describe motion.&lt;br /&gt;&lt;br /&gt;Because science has used solvable mathematics, proofs, and equations to discover how Things Work, that has been the class of problems solved.  Some problems in biological growth, physics, and such have been impossible to solve, and so have been ignored or swept under the rug.&lt;br /&gt;&lt;br /&gt;What Wolfram proposes in A New Kind of Science is that there are many structures and processes in the universe that can not be described by linear math.  Instead there are automatons and computer programs that can easily describe and model some processes.  Not only does this technique model many processes that were previously 'complex' but great complexity can often flow from very simple processes.  A familiar example of this is fractals, where a simple set of rules generate a very detailed and complex drawing.&lt;br /&gt;&lt;br /&gt;The other side of this coin is that some problems and models can never be proven no matter how long you simulate or compute them.  Science hates to say 'I don't know', but Wolfram clearly states that there are some things that can not be known.&lt;br /&gt;&lt;br /&gt;Much of the book centers around the idea of generating complexity by way of ultra simple programs, and finding out just how simple you can get and still get huge complexity.&lt;br /&gt;&lt;br /&gt;The book touches on biological organisms, stellar systems, fluid flow, the mind, free will, evolution, religion, society, and of course, mathematics.&lt;br /&gt;&lt;br /&gt;So, when reading the book one thing stood out as odd.  One is the general use of I, My, This Science, where Wolfram's ideas and science is 'All New and Improved!' and will revolutionize science.  This gives it about the same tone as crackpots on the internet with some hair-brained theory that will change the world and has never been know before (tm).  The difference with this book is that Wolfram is correct!  Books such as The Origin of the Species have none of that tone.&lt;br /&gt;&lt;br /&gt;Another thing that will help with this book is to not get stuck on the huge amount of ideas and processes presented.  You don't have to understand every concept and program process presented.  If I read this and learned to understand every mathematical concept presented in depth it would take years to read.&lt;br /&gt;&lt;br /&gt;In the end the core idea is of &lt;b&gt;The Principle of Computational Equivalence&lt;/B&gt;.  The idea is that it does not matter whether a program is run on a computer, in a biological system, or a flow of atoms in a fluid, it is all the same. This is much like how the equation of gravity, F = MmG/r^2 is equivalent to what actual gravity does.  But the equation and computing it is not what gravity is doing in the real world.  It is a model that matches what we see, so gives understanding.&lt;br /&gt;&lt;br /&gt;The other core idea is that the only way of discovering the outcome of some simple systems is to run the system to completion. For example, it is impossible to determine whether pi ever repeats, except to keep computing digits of pi until it does. (And so far it has not after billions of digits.)&lt;br /&gt;&lt;br /&gt;The final paragraph is a gem...&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;And indeed in the end the Principle of Computational Equivalence encapsulates both the ultimate power and the ultimate weakness of science. For it implies that all the wonders of the universe can in effect be captured by simple rules, yet it shows that there can be no way to know all the consequences of these rules, except in effect just to watch and see how they unfold.&lt;/blockquote&gt;&lt;br /&gt;Wow.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-5650625655206299825?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/5650625655206299825/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=5650625655206299825' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/5650625655206299825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/5650625655206299825'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2012/01/new-kind-of-science-stephen-wolfram.html' title='A New Kind of Science - Stephen Wolfram'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-184784428318500088</id><published>2012-01-01T19:52:00.000-08:00</published><updated>2012-01-01T19:52:51.870-08:00</updated><title type='text'>Honda Civic Hybrid 2005 Headlamp Replacement</title><content type='html'>Ok, &lt;br /&gt;&lt;br /&gt;A headlight blew.  So I had to replace it.&lt;br /&gt;&lt;br /&gt;The high beams are toward the middle of the car and are fairly easy to replace.  &lt;br /&gt;&lt;br /&gt;In general you rotate the lamp to the left so it unclips. Then push in the tab on the wire harness end and pull the lamp loose.&lt;br /&gt;&lt;br /&gt;Don't touch the bulbs you are putting in ever.  The oil from your fingers will shatter the bulb once it is on for a while.&lt;br /&gt;&lt;br /&gt;The low beams are the next outward from the center of the car.  They are difficult.&lt;br /&gt;On the driver side the battery is in the way.  On the passenger side the fuel pump (?) is in the way.&lt;br /&gt;&lt;br /&gt;The instructions say on the driver side you have to remove the wiper fluid reservoir, but I think the Hybrid is different.&lt;br /&gt;&lt;br /&gt;What I did on the passenger side is go in through the wheel well.  You use a screwdriver to pry out the two black plastic clips and then bend the wheel well plastic cover down so you can get your hand in. (Major yoga here.) I assume you do the same on the driver side.&lt;br /&gt;&lt;br /&gt;The left and right blinker are accessed through the wheel well too.&lt;br /&gt;&lt;br /&gt;Oh, you have to turn the steering wheel all the way to one side so the wheel well is exposed and you can get in there.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-184784428318500088?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/184784428318500088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=184784428318500088' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/184784428318500088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/184784428318500088'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2012/01/honda-civic-hybrid-headlamp-replacement.html' title='Honda Civic Hybrid 2005 Headlamp Replacement'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-3911342983502340777</id><published>2011-12-19T12:47:00.000-08:00</published><updated>2011-12-19T12:47:03.220-08:00</updated><title type='text'>BMP085 Code Revisited Floating Point Version</title><content type='html'>Previously I posted a correction to the Bosch BMP085 calculation.&lt;br /&gt;Today I found this paper,&amp;nbsp;&lt;a href="http://wmrx00.sourceforge.net/Arduino/BMP085-Calcs.pdf"&gt;BMP085-Calcs.pdf&lt;/a&gt;&amp;nbsp;but was unable to find C code to go with the paper.&lt;br /&gt;&lt;br /&gt;This code results in more refined altitude increments and uses the whole accuracy. &amp;nbsp;The old integer code rounds of some bits and makes altitude increments more chunky.&lt;br /&gt;&lt;br /&gt;(Very important in some altitude based feedback systems and others)&lt;br /&gt;&lt;br /&gt;So I dug in and implemented it...&lt;br /&gt;&lt;br /&gt;My variables, then the constant calcs, then the calc, then the test code.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;int Baro_ac1, Baro_ac2, Baro_ac3, Baro_b1, Baro_b2, Baro_mb, Baro_mc, Baro_md;&lt;br /&gt;unsigned int Baro_ac4, Baro_ac5, Baro_ac6;&lt;br /&gt;&lt;br /&gt;float Baro_fc3;&lt;br /&gt;float Baro_fc4;&lt;br /&gt;float Baro_fb1;&lt;br /&gt;float Baro_fc5;&lt;br /&gt;float Baro_fc6;&lt;br /&gt;float Baro_fmc;&lt;br /&gt;float Baro_fmd;&lt;br /&gt;float Baro_fx0;&lt;br /&gt;float Baro_fx1;&lt;br /&gt;float Baro_fx2;&lt;br /&gt;float Baro_fy0;&lt;br /&gt;float Baro_fy1;&lt;br /&gt;float Baro_fy2;&lt;br /&gt;float Baro_fp0;&lt;br /&gt;float Baro_fp1;&lt;br /&gt;float Baro_fp2;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;// And calculate derrived constants used by BaroCalcFloat()&lt;br /&gt;// from http://wmrx00.sourceforge.net/Arduino/BMP085-Calcs.pdf&lt;br /&gt;Baro_fc3 = 160.0f * powf(2.0f, -15.0) * Baro_ac3;&lt;br /&gt;Baro_fc4 = 0.001f * powf(2.0f, -15.0) * Baro_ac4;&lt;br /&gt;Baro_fb1 = (160.0f * 160.0f) * powf(2.0f, -30.0) * Baro_b1;&lt;br /&gt;&lt;br /&gt;Baro_fc5 = Baro_ac5 * powf(2.0f, -15.0) / 160.0f;&lt;br /&gt;Baro_fc6 = Baro_ac6;&lt;br /&gt;Baro_fmc = Baro_mc * powf(2.0f, 11.0) / (160.0f * 160.0f);&lt;br /&gt;Baro_fmd = Baro_md / 160.0f;&lt;br /&gt;&lt;br /&gt;Baro_fx0 = Baro_ac1;&lt;br /&gt;Baro_fx1 = 160.0f * powf(2.0f, -13.0) * Baro_ac2;&lt;br /&gt;Baro_fx2 = (160.0f * 160.0f) * powf(2.0f, -25.0) * Baro_b2;&lt;br /&gt;&lt;br /&gt;Baro_fy0 = Baro_fc4 * powf(2.0f, 15.0);&lt;br /&gt;Baro_fy1 = Baro_fc4 * Baro_fc3;&lt;br /&gt;Baro_fy2 = Baro_fc4 * Baro_fb1;&lt;br /&gt;&lt;br /&gt;Baro_fp0 = (3791.0f - 8.0f)/1600.0f;&lt;br /&gt;Baro_fp1 = 1.0f - 7357.0f * powf(2.0f, -20.0);&lt;br /&gt;Baro_fp2 = 3038.0f * 100.0f * powf(2.0f, -36.0);&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;float tu = BaroState.rawTemperature;&lt;br /&gt;// Assumes Baro_oss highest precision BARO_OSS_MODE_ULTRA_HIGH_RES.&lt;br /&gt;float pu = BaroState.rawPressure / 256.0f;&lt;br /&gt;&lt;br /&gt;float alpha = Baro_fc5 * (tu - Baro_fc6);&lt;br /&gt;float Tc = alpha + Baro_fmc / (alpha + Baro_fmd);&lt;br /&gt;BaroState.temperatureC = Tc;&lt;br /&gt;&lt;br /&gt;float s = Tc - 25.0f;&lt;br /&gt;float x = Baro_fx2 * (s * s) + Baro_fx1 * s + Baro_fx0;&lt;br /&gt;float y = Baro_fy2 * (s * s) + Baro_fy1 * s + Baro_fy0;&lt;br /&gt;float z = (pu - x) / y;&lt;br /&gt;BaroState.pressurePa = Baro_fp2 * (z * z) + Baro_fp1 * z + Baro_fp0;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;void BaroTestMathFloat()&lt;br /&gt;{&lt;br /&gt;mainMessagePrint(ROUTE_DEBUG, "Baro Test Math (float)\r\n");&lt;br /&gt;&lt;br /&gt;Baro_ac1 =7911;&lt;br /&gt;Baro_ac2 = -934;&lt;br /&gt;Baro_ac3 = -14306;&lt;br /&gt;Baro_ac4 = 31567;&lt;br /&gt;Baro_ac5 = 25671;&lt;br /&gt;Baro_ac6 = 18974;&lt;br /&gt;Baro_b1 = 5498;&lt;br /&gt;Baro_b2 = 46;&lt;br /&gt;Baro_mb = -32768;&lt;br /&gt;Baro_mc = -11075;&lt;br /&gt;Baro_md = 2432;&lt;br /&gt;&lt;br /&gt;Baro_fc3 = 160.0f * powf(2.0f, -15.0) * Baro_ac3;&lt;br /&gt;Baro_fc4 = 0.001f * powf(2.0f, -15.0) * Baro_ac4;&lt;br /&gt;Baro_fb1 = (160.0f * 160.0f) * powf(2.0f, -30.0) * Baro_b1;&lt;br /&gt;mainMessagePrint(ROUTE_DEBUG, "fc3 %f fc4 %f fb1 %f", Baro_fc3, Baro_fc4, Baro_fb1);&lt;br /&gt;&lt;br /&gt;Baro_fc5 = Baro_ac5 * powf(2.0f, -15.0) / 160.0f;&lt;br /&gt;Baro_fc6 = Baro_ac6;&lt;br /&gt;Baro_fmc = Baro_mc * powf(2.0f, 11.0) / (160.0f * 160.0f);&lt;br /&gt;Baro_fmd = Baro_md / 160.0f;&lt;br /&gt;mainMessagePrint(ROUTE_DEBUG, "fc5 %f fc6 %f fmc %f fmd %f",&lt;br /&gt;Baro_fc5, Baro_fc6, Baro_fmc, Baro_fmd);&lt;br /&gt;&lt;br /&gt;Baro_fx0 = Baro_ac1;&lt;br /&gt;Baro_fx1 = 160.0f * powf(2.0f, -13.0) * Baro_ac2;&lt;br /&gt;Baro_fx2 = (160.0f * 160.0f) * powf(2.0f, -25.0) * Baro_b2;&lt;br /&gt;mainMessagePrint(ROUTE_DEBUG, "x %f %f %f",&lt;br /&gt;Baro_fx0, Baro_fx1, Baro_fx2);&lt;br /&gt;&lt;br /&gt;Baro_fy0 = Baro_fc4 * powf(2.0f, 15.0);&lt;br /&gt;Baro_fy1 = Baro_fc4 * Baro_fc3;&lt;br /&gt;Baro_fy2 = Baro_fc4 * Baro_fb1;&lt;br /&gt;mainMessagePrint(ROUTE_DEBUG, "y %f %f %f",&lt;br /&gt;Baro_fy0, Baro_fy1, Baro_fy2);&lt;br /&gt;&lt;br /&gt;Baro_fp0 = (3791.0f - 8.0f)/1600.0f;&lt;br /&gt;Baro_fp1 = 1.0f - 7357.0f * powf(2.0f, -20.0);&lt;br /&gt;Baro_fp2 = 3038.0f * 100.0f * powf(2.0f, -36.0);&lt;br /&gt;mainMessagePrint(ROUTE_DEBUG, "p %f %f %f",&lt;br /&gt;Baro_fp0, Baro_fp1, Baro_fp2);&lt;br /&gt;&lt;br /&gt;BaroState.rawTemperature = 0x69EC;&lt;br /&gt;BaroState.rawPressure = 0x982FC0;&lt;br /&gt;Baro_oss = BARO_OSS_MODE_ULTRA_HIGH_RES;&lt;br /&gt;&lt;br /&gt;float tu = BaroState.rawTemperature;&lt;br /&gt;// Assumes Baro_oss highest precision BARO_OSS_MODE_ULTRA_HIGH_RES.&lt;br /&gt;float pu = BaroState.rawPressure / 256.0f;&lt;br /&gt;&lt;br /&gt;mainMessagePrint(ROUTE_DEBUG, "rt %f  rp %f", tu, pu);&lt;br /&gt;&lt;br /&gt;float alpha = Baro_fc5 * (tu - Baro_fc6);&lt;br /&gt;float Tc = alpha + Baro_fmc / (alpha + Baro_fmd);&lt;br /&gt;BaroState.temperatureC = Tc;&lt;br /&gt;mainMessagePrint(ROUTE_DEBUG, "a %f  Tc %f", alpha, Tc);&lt;br /&gt;&lt;br /&gt;float s = Tc - 25.0f;&lt;br /&gt;float x = Baro_fx2 * (s * s) + Baro_fx1 * s + Baro_fx0;&lt;br /&gt;float y = Baro_fy2 * (s * s) + Baro_fy1 * s + Baro_fy0;&lt;br /&gt;float z = (pu - x) / y;&lt;br /&gt;BaroState.pressurePa = Baro_fp2 * (z * z) + Baro_fp1 * z + Baro_fp0;&lt;br /&gt;mainMessagePrint(ROUTE_DEBUG, "s %f  x %f  y %f  z %f  p %f", s, x, y, z, BaroState.pressurePa);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-3911342983502340777?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/3911342983502340777/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=3911342983502340777' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/3911342983502340777'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/3911342983502340777'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2011/12/bmp085-code-revisited-floating-point.html' title='BMP085 Code Revisited Floating Point Version'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-7298746625950967976</id><published>2011-11-26T15:04:00.000-08:00</published><updated>2011-11-26T15:04:35.798-08:00</updated><title type='text'>On "Book Code"</title><content type='html'>Ok,&lt;br /&gt;So you buy that nifty new book on Game Programming. One would assume the people writing the chapters would know what they are doing, or at least have used the code in an actual game. &amp;nbsp;Nope.&lt;br /&gt;&lt;br /&gt;Always understand what the code does, and be ready for&amp;nbsp;problems&amp;nbsp;arising from the difference between your goal, to write a working&amp;nbsp;commercial&amp;nbsp;game, and the writer's goal, to&amp;nbsp;write&amp;nbsp;a chapter in a book.&lt;br /&gt;&lt;br /&gt;I have run into this in two places&amp;nbsp;recently. &amp;nbsp;One is the network library MTUDP in&lt;br /&gt;&lt;h3 class="r" style="background-color: white; color: #222222; font-family: arial, sans-serif; font-size: medium; font-weight: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: hidden; overflow-y: hidden; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-overflow: ellipsis; white-space: nowrap;"&gt;&lt;a href="http://books.google.com/books?id=VESdhowqhBUC&amp;amp;pg=PA282&amp;amp;lpg=PA282&amp;amp;dq=MTUDP.cpp&amp;amp;source=bl&amp;amp;ots=9uA4o5_QAx&amp;amp;sig=UWQEOEHvmI5ZKMhxKbpVldDnUjg&amp;amp;hl=en&amp;amp;ei=EW_RTsC-G8WsiAKPkO35Cw&amp;amp;sa=X&amp;amp;oi=book_result&amp;amp;ct=result&amp;amp;resnum=4&amp;amp;ved=0CDIQ6AEwAw" style="color: #1122cc; cursor: pointer;"&gt;Advanced 3D game programming with DirectX 10.0&lt;/a&gt;&amp;nbsp;and the other has been bullet physics.&amp;nbsp;&lt;/h3&gt;&lt;div&gt;MTUDP is a good idea but not done and tested well. (If you want my rewrite, email me) and bullet physics is a&amp;nbsp;university&amp;nbsp;project to try new ideas in physics. &amp;nbsp;In my case I want to create a open ended infinite zombie game with on-the-fly AI generation of all game content.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There is an echo here of operating system issues. &amp;nbsp;Was the OS written to make money for a huge corporation, or by hobbyists to make a system they want to work in and use, or as a fashion statement for elite computer users? (Ok, you guess which three OSs to which I am referring.0&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Oh, well, end of rant. And end of three weeks of wasted time trying to debug and make a&amp;nbsp;fundamentally&amp;nbsp;broken library work.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;TF&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-7298746625950967976?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/7298746625950967976/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=7298746625950967976' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/7298746625950967976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/7298746625950967976'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2011/11/on-book-code.html' title='On &quot;Book Code&quot;'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-3730813686259330659</id><published>2011-11-21T09:18:00.000-08:00</published><updated>2011-11-26T15:05:39.334-08:00</updated><title type='text'>MTUDP.cpp More Fixes</title><content type='html'>WARNING - I should remove this post, but instead will give a warning. &amp;nbsp;Do not use the MTUDP.cpp library as is. &amp;nbsp;It has many bugs and makes a fatal mistake. &amp;nbsp;The user ID is the IP address. &amp;nbsp;This breaks if there is a fire wall in the way, and there is always a firewall. &amp;nbsp;I have nearly rewritten the library with very little of the original code left over.&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Ok, turns out the previous post was not a complete fix for the Ack code.&lt;br /&gt;As usual the blog mangles the C code a bit, but you should be able to copy this, else email me for a complete copy.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt; unsigned short NetLibHost::ProcessIncomingACKs( char *pBuffer, unsigned short len, DWORD receiveTime )&lt;br /&gt; {&lt;br /&gt;  UNREFERENCED_PARAMETER(len);&lt;br /&gt;  // Get the number of ACKs in this message, not counting the base ACK.&lt;br /&gt;  unsigned char numAcks, mask, *ptr;&lt;br /&gt;  DWORD         basePacketID, ackID;&lt;br /&gt;&lt;br /&gt;  ptr = (unsigned char *)pBuffer;&lt;br /&gt;&lt;br /&gt;  // The story: We want to ack each received packet. &lt;br /&gt;  // But if we have received a series of packets we only&lt;br /&gt;  // have to ack the highest numbered one and we assume all the lesser packets are ack'd too.&lt;br /&gt;  // But then there can be some higher number packets we have received with some gaps.&lt;br /&gt;  // So we send the highest received packet so far with no unreceived packets less than it, then&lt;br /&gt;  // have bytes with the bits representing yes/no acks for higher numbered packets.'&lt;br /&gt;  // So say we have received  3,4,5,6,7,9,10,11,13&lt;br /&gt;  // The base would be 7 since we have all pacjets up to that,&lt;br /&gt;  // Then the next byte is the bits 0x00 | 0x40 | 0x20 | 0x10 | 0x00 | 0x40&lt;br /&gt;  // for packets 8,9,10,11,12,13 respectively.&lt;br /&gt;&lt;br /&gt;  // Get the base packet ID, which indicates all the ordered packets received so far.&lt;br /&gt;  memcpy( &amp;amp;basePacketID, ptr, sizeof( DWORD ) );&lt;br /&gt;  ptr += sizeof( DWORD );&lt;br /&gt;  // Get the number of additional ACKs.&lt;br /&gt;  // TODO - Keene - Runs off the end if Ack record was truncated to fit!&lt;br /&gt;  // Solution: don't ever make packets messages that are too large, e.g. 3k&lt;br /&gt;  numAcks = *ptr;&lt;br /&gt;  ptr++;&lt;br /&gt;  // Zero the byte so if there is a one off error in bits, it is not a false ack.&lt;br /&gt;  *ptr = 0x00;&lt;br /&gt;  ackID = d_outQueue.GetLowestID();&lt;br /&gt;&lt;br /&gt;#if defined( _DEBUG_VERBOSE )&lt;br /&gt;  OUTPUTREPORT3( "&amp;lt;   Ack low=%04d base=%04d end=%04d\n", ackID, basePacketID, basePacketID + numAcks );&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;  // Can get stuck in loop here if corrupt data.&lt;br /&gt;  int debugCount = 0;&lt;br /&gt;  while( ackID &amp;lt;= basePacketID )&lt;br /&gt;  {&lt;br /&gt;   debugCount++;&lt;br /&gt;   // The packet has been ack's so update average ping time.&lt;br /&gt;   ACKPacket( ackID, receiveTime );&lt;br /&gt;   ackID++;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  mask = 0x80;&lt;br /&gt;&lt;br /&gt;  // TODO - Keene - Runs off the end if ack record was truncated to fit!&lt;br /&gt;  // Solution: don't ever make packets messages that are too large, e.g. 3k&lt;br /&gt;  while( ackID &amp;lt; basePacketID + numAcks )&lt;br /&gt;  {&lt;br /&gt;   if( mask == 0x00 )&lt;br /&gt;   {&lt;br /&gt;    mask = 0x80;&lt;br /&gt;    ptr++;&lt;br /&gt;    // Zero the byte so if there is a one off error in bits, it is not a false ack.&lt;br /&gt;    *ptr = 0x00;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   if( ( *ptr &amp;amp; mask ) != 0 )&lt;br /&gt;   {&lt;br /&gt;    ACKPacket( ackID, receiveTime );&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   mask &amp;gt;&amp;gt;= 1;&lt;br /&gt;   ackID++;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  return (unsigned short)(ptr - (unsigned char *)pBuffer);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; unsigned short NetLibHost::ProcessIncomingReliable( char *pBuffer, unsigned short maxLen, DWORD receiveTime )&lt;br /&gt; {&lt;br /&gt;  maxLen;&lt;br /&gt;  // Process any messages in the packet.&lt;br /&gt;  DWORD           packetID;&lt;br /&gt;  char            *readPtr;&lt;br /&gt;  unsigned short  length;&lt;br /&gt;&lt;br /&gt;  readPtr = pBuffer;&lt;br /&gt;  memcpy( &amp;amp;packetID, readPtr, sizeof( DWORD ) );&lt;br /&gt;  readPtr += sizeof( DWORD );&lt;br /&gt;  memcpy( &amp;amp;length, readPtr, sizeof( unsigned short ) );&lt;br /&gt;  readPtr += sizeof( unsigned short );&lt;br /&gt;#if defined( _DEBUG_VERBOSE )&lt;br /&gt;  OUTPUTREPORT2( "&amp;lt;   %04d (%d) R\n", packetID, length );&lt;br /&gt;#endif&lt;br /&gt;  // If this message is a packet, queue the data&lt;br /&gt;  // to be dealt with by the application later.&lt;br /&gt;  d_inQueue.AddPacket( packetID, (char *)readPtr, length, receiveTime );&lt;br /&gt;  readPtr += length;&lt;br /&gt;&lt;br /&gt;  // Should we build an ACK message?&lt;br /&gt;  if( d_inQueue.GetCount() == 0 )&lt;br /&gt;  {&lt;br /&gt;   return (unsigned short)( readPtr - pBuffer );&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // Build the new ACK message.&lt;br /&gt;  DWORD         lowest, highest, ackID;&lt;br /&gt;  unsigned char mask, *ptr;&lt;br /&gt;&lt;br /&gt;  lowest = d_inQueue.GetCurrentID();&lt;br /&gt;  highest = d_inQueue.GetHighestID();&lt;br /&gt;&lt;br /&gt;  // Cap the highest so as not to overflow the ACK buffer&lt;br /&gt;  // (or spend too much time building ACK messages).&lt;br /&gt;  // (Was bug here because ACK_MAXPERMSG was 256 which does not fit in a byte.)&lt;br /&gt;  if( highest &amp;gt; lowest + ACK_MAXPERMSG )&lt;br /&gt;  {&lt;br /&gt;   highest = lowest + ACK_MAXPERMSG;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;#if defined( _DEBUG_VERBOSE )&lt;br /&gt;  OUTPUTREPORT2( " &amp;gt;  %04d ack to %04d ", lowest, highest );&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;  // The story: We want to ack each received packet. &lt;br /&gt;  // But if we have received a series of packets we only&lt;br /&gt;  // have to ack the highest numbered one and we assume all the lesser packets are ack'd too.&lt;br /&gt;  // But then there can be some higher number packets we have received with some gaps.&lt;br /&gt;  // So we send the highest received packet so far with no unreceived packets less than it, then&lt;br /&gt;  // have bytes with the bits representing yes/no acks for higher numbered packets.'&lt;br /&gt;  // So say we have received  3,4,5,6,7,9,10,11,13&lt;br /&gt;  // The base would be 7 since we have all pacjets up to that,&lt;br /&gt;  // Then the next byte is the bits 0x00 | 0x40 | 0x20 | 0x10 | 0x00 | 0x40&lt;br /&gt;  // for packets 8,9,10,11,12,13 respectively.&lt;br /&gt;&lt;br /&gt;  ptr = (unsigned char *)d_ackBuffer;&lt;br /&gt;  // Send the base packet ID, which is the ID of the last ordered packet received.&lt;br /&gt;  memcpy( ptr, &amp;amp;lowest, sizeof( DWORD ) );&lt;br /&gt;  ptr += sizeof( DWORD );&lt;br /&gt;  // Add the number of additional ACKs.&lt;br /&gt;  *ptr = (unsigned char)(highest - lowest);&lt;br /&gt;  ptr++;&lt;br /&gt;  // Zero the byte so if there is a one off error in bits, it is not a false ack.&lt;br /&gt;  *ptr = 0x00;&lt;br /&gt;&lt;br /&gt;  ackID = lowest + 1;&lt;br /&gt;  mask = 0x80;&lt;br /&gt;&lt;br /&gt;  while( ackID &amp;lt;= highest )&lt;br /&gt;  {&lt;br /&gt;   if( mask == 0x00 )&lt;br /&gt;   {&lt;br /&gt;    mask = 0x80;&lt;br /&gt;    ptr++;&lt;br /&gt;    // Zero the byte so if there is a one off error in bits, it is not a false ack.&lt;br /&gt;    *ptr = 0x00;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   // Is there a packet with id 'ackID' ?&lt;br /&gt;   if( d_inQueue.UnorderedPacketIsQueued( ackID ) == true )&lt;br /&gt;   {&lt;br /&gt;    *ptr |= mask;  // There is&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;    *ptr &amp;amp;= ~mask;  // There isn't&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   mask &amp;gt;&amp;gt;= 1;&lt;br /&gt;   ackID++;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;#if defined( _DEBUG_VERBOSE )&lt;br /&gt;  OUTPUTREPORT0( "\n" );&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;  // Record the ammount of the ackBuffer used.&lt;br /&gt;  d_ackLength = (unsigned short)(ptr - (unsigned char *)d_ackBuffer);&lt;br /&gt;  assert(d_ackLength &amp;lt;= ACK_BUFFERLENGTH);&lt;br /&gt;&lt;br /&gt;  // return the number of bytes read from buffer&lt;br /&gt;  return (unsigned short)( readPtr - pBuffer );&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-3730813686259330659?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/3730813686259330659/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=3730813686259330659' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/3730813686259330659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/3730813686259330659'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2011/11/mtudpcpp-more-fixes.html' title='MTUDP.cpp More Fixes'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-8886991093004917075</id><published>2011-11-20T21:09:00.000-08:00</published><updated>2011-11-26T15:05:55.952-08:00</updated><title type='text'>MTUDP.cpp NetLib Bug fixes.</title><content type='html'>WARNING - I should remove this post, but instead will give a warning. &amp;nbsp;Do not use the MTUDP.cpp library as is. &amp;nbsp;It has many bugs and makes a fatal mistake. &amp;nbsp;The user ID is the IP address. &amp;nbsp;This&amp;nbsp;breaks&amp;nbsp;if there is a fire wall in the way, and there is always a firewall. &amp;nbsp;I have nearly rewritten the library with very little of the original code left over.&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;I have been using the MTUDP.cpp library from the book&lt;br /&gt;&lt;i&gt;Advanced 3D game programming with DirectX 10.0 By Peter Walsh&lt;/i&gt;&lt;br /&gt;&lt;span class="addmd" style="background-color: white; font-family: Arial, sans-serif; margin-left: 2px; white-space: nowrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="addmd" style="background-color: white; font-family: Arial, sans-serif; margin-left: 2px; white-space: nowrap;"&gt;The library has many bugs that I have been fixing over time.&lt;/span&gt;&lt;br /&gt;&lt;span class="addmd" style="background-color: white; font-family: Arial, sans-serif; margin-left: 2px; white-space: nowrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="addmd" style="background-color: white; font-family: Arial, sans-serif; margin-left: 2px; white-space: nowrap;"&gt;Several are.&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: Arial, sans-serif; white-space: nowrap;"&gt;..&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The library send all packets twice, which is unnecessary.  So in MTUDP.cpp I comment out the three sections where that happens. Look for secondPacket to find the blocks.&lt;br /&gt;&lt;br /&gt;In NetLibHost.cpp there is a big problem with the Ack generation loops.  They initialize the mask to 0x80 and if there are no additional Acks, then the later count returned is off by one since the mask is not zero.  The mask should be initialized to 0x00. (two places in the code. Search for mask = 0x80;) WARNING - WRONG - SEE NEXT POST&lt;br /&gt;&lt;br /&gt;The Ack record can be truncated in AddAckMessage it checks to see if the the length is exceeded and if it is it truncates, but the count of additional acks is not adjusted, boom! I don't have a fix for this except make sure no packets approach the max packet size boundary.  I put an assert in to check if you run off the end.&lt;br /&gt;&lt;br /&gt;I noticed that on creation the Host record does not initialize the ping times and last packet time.  Hmmm, haven't worked on that one yet.&lt;br /&gt;&lt;br /&gt;Hope this saved some poor soul some time.&lt;span class="Apple-style-span" style="font-family: Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="white-space: nowrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, sans-serif; font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="white-space: nowrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="white-space: nowrap;"&gt;TF&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="addmd" style="background-color: white; font-family: Arial, sans-serif; font-size: 13px; margin-left: 2px; white-space: nowrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-8886991093004917075?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/8886991093004917075/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=8886991093004917075' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/8886991093004917075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/8886991093004917075'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2011/11/mtudpcpp-netlib-bug-fixes.html' title='MTUDP.cpp NetLib Bug fixes.'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-4115976793382846990</id><published>2011-10-18T13:51:00.000-07:00</published><updated>2011-10-26T08:04:22.699-07:00</updated><title type='text'>A change of weather</title><content type='html'>I just read (slogged through) the rather lengthy and full-of-Greek-letters&amp;nbsp;paper,&amp;nbsp;&lt;a href="http://rspa.royalsocietypublishing.org/content/466/2114/303.full.pdf+html"&gt;http://rspa.royalsocietypublishing.org/content/466/2114/303.full.pdf+html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Wow, I have been a long standing global warming skeptic. &amp;nbsp;This paper has been quite an awakening. &lt;br /&gt;&lt;br /&gt;In this paper&amp;nbsp;Mike Lockwood discusses with real numbers, real data, and the best science available all the rumors and&amp;nbsp;innuendos&amp;nbsp;on the internet about climate.&lt;br /&gt;&lt;br /&gt;For example one of my favorites has been "The solar wind varies during sunspot cycles and the kinetic impact of the solar wind on the upper atmosphere could be causing warming, so at solar minimums the climate should cool." &amp;nbsp;Turns out that has been studied and estimated and is about 0.02 watts per square meter (page 323). &amp;nbsp;Global warming is in the range of 5 watts per square meter of effective heating.&lt;br /&gt;&lt;br /&gt;In many places there are fairly wide ranges of estimates and he freely admits that. &amp;nbsp;But the range of error in "Well, I think such and such because it just seems right" is one heck of a lot wider in error.&lt;br /&gt;&lt;br /&gt;One thing I get from reading many different scientific papers on climate (you know, the ones that are PDFs and highly technical, dense in facts and data, and unemotional, and written by actual scientists) is that the science of climate is in a huge state of flux. Planetary science is in a similar state and for the same reasons, we have satellites that are getting better and better data all the time.&lt;br /&gt;&lt;br /&gt;The basic issue is not "do we cause global warming" nor is it "is climate mostly Sun-controlled". The real issue is "what fraction of the total climate is determined by various causes, and how?" &amp;nbsp;So in the climate debate, everyone is correct, but how correct and whom should policy makers listen to is the real issue. Also it may be that the largest climate fluctuation controller over a century or two is the sun + ocean cycles + whatever, but a very long term trend is that humans are warming the planet. &amp;nbsp;This means the highs get a little higher and the lows a little warmer, which could have&amp;nbsp;profound&amp;nbsp;effects on human well being.&lt;br /&gt;&lt;br /&gt;There should also be a policy debate on what effect humans are having on climate and what can we do about it vs. what does it cost in short and long term resource investment. &amp;nbsp;This debate is not happening at all in the general public sector.&lt;br /&gt;&lt;br /&gt;So here are the fundamental questions and where my opinion has of late changed drastically:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;Is global warming and/or climate change happening.&lt;/b&gt; &amp;nbsp;Yes. &amp;nbsp;No change here. &amp;nbsp;Everyone knows this and climate has been fluctuating for the last several billion years.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Are we causing global warming?&lt;/b&gt; Big change here - Yes. &amp;nbsp;The&amp;nbsp;evidence&amp;nbsp;points to this. &amp;nbsp;It is not perfectly conclusive, but is the best most logical science we have now. &amp;nbsp;This evidence is&amp;nbsp;buried&amp;nbsp;under a mountain of opinion, politics, and social fear of the&amp;nbsp;consequences, yet at the same time is in plain sight on the internet. &amp;nbsp;You just have to look for it and train your self to read the&amp;nbsp;academic&amp;nbsp;jargon. &amp;nbsp;Not that hard with practice. (I cut my teeth on Scientific American and other more technical reading so I learned this at about age 10.)&lt;/li&gt;&lt;li&gt;&lt;b&gt;Can we do any thing about it?&lt;/b&gt; &amp;nbsp;Yes, but it will require changes in basic&amp;nbsp;societal&amp;nbsp;values. &amp;nbsp;There are even some very simple solutions like injecting Sulfur Dioxide into the upper atmosphere, which would not be all that expensive or difficult. &amp;nbsp;(&lt;a href="http://www.scientificamerican.com/article.cfm?id=poll-finds-support-for-geoengineering-blocking-sunshine"&gt;http://www.scientificamerican.com/article.cfm?id=poll-finds-support-for-geoengineering-blocking-sunshine&lt;/a&gt;) But see #4 below. (An experiment is happening very soon in England to test this idea.) There are many ideas such as lower carbon&amp;nbsp;emissions, mirrors in space, etc.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Will we do anything?&lt;/b&gt; &amp;nbsp;The current intelligence and mindset of politicians in all the world governments (not just the United States) is so&amp;nbsp;pitifully&amp;nbsp;low as to make it doubtful anything effective can or will be done. I suggest the video "Pale Blue Dot" on youtube. It is very unfortunate that the United States is in the perfect position to lead the world into a more sustainable future, but does not. &amp;nbsp;Such leadership will take more than a well connected oil man, or a hansome charismatic speaker. &amp;nbsp;It will take an actual leader of&amp;nbsp;talent, integrity, and compromise. &amp;nbsp;Good luck with either political party of the US ever fielding such a candidate. &amp;nbsp;That future world does not need to be a world of low income peasant medieval farmers, it could be a very nice world, in many ways better that the current one. &amp;nbsp;The only way a real solution (not the joke that the Kyoto Protocol is) will happen is when the general population decides to make it happen. &amp;nbsp;Historically our track record for such response is not too good. &amp;nbsp;Neither the Democrats, nor Republicans, nor the Tree Huggers have the skills or mindset to solve this. None of the above parties have any interest in solving climate issues. &amp;nbsp;The&amp;nbsp;politicians&amp;nbsp;love a Big Crisis and the Al Gores of the world would be out of a job if a solution a simple as&amp;nbsp;Sulfur&amp;nbsp;Dioxide injection worked. (Estimated cost $200 million to solve the whole problem, untested).&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;As Jared Diamond said, "Cautious&amp;nbsp;optimism".&lt;br /&gt;&lt;ol&gt;&lt;/ol&gt;&lt;div&gt;TF&lt;/div&gt;&lt;div&gt;&lt;br /&gt;P.S. History never comes out the way one predicts or expects. Life is an adventure.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-4115976793382846990?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/4115976793382846990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=4115976793382846990' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/4115976793382846990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/4115976793382846990'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2011/10/change-of-weather.html' title='A change of weather'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-329624684837910913</id><published>2011-09-07T11:20:00.000-07:00</published><updated>2011-09-07T11:20:00.204-07:00</updated><title type='text'>Stupid Programmer Tricks, C++</title><content type='html'>Ok,&lt;br /&gt;I've been diving into C++ after not using it for a long time. &amp;nbsp;There are some pitfalls that have cost allot of time.&lt;br /&gt;Rather than clutter things up with angry exclamation points to show frustration, I'll make the simple statements.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Destructors must be declared virtual in the base class or the child class destructor will not get called.&lt;/li&gt;&lt;li&gt;You can declare a variable in a base class and then declare it in the child class and no compiler error or warning gets generated. &amp;nbsp;But they are different variables and when you set, NULL, or delete one, the other is untouched, with very ugly side effects.&lt;/li&gt;&lt;li&gt;You must always&amp;nbsp;initialize&amp;nbsp;variables or they will contain garbage. &amp;nbsp;In particular, you must set pointers to NULL&lt;/li&gt;&lt;/ol&gt;Now I bet there are compiler flags I could have set or some such, but they are not the default Visual Studio C++ settings. Hope I saved you some time.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-329624684837910913?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/329624684837910913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=329624684837910913' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/329624684837910913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/329624684837910913'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2011/09/stupid-programmer-tricks-c.html' title='Stupid Programmer Tricks, C++'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-4463722332828541785</id><published>2011-08-20T17:02:00.000-07:00</published><updated>2011-08-20T17:11:57.175-07:00</updated><title type='text'>Permaculture and Rocks - Mico-dams</title><content type='html'>So I was&amp;nbsp;studying&amp;nbsp;my yard for about an hour today. &amp;nbsp;This "study"&amp;nbsp;consists&amp;nbsp;of walking around while the sprinklers run and just looking. &amp;nbsp;The back of my yard is a very steep slope up to the yard behind us. &amp;nbsp;I'm in Utah so we are in an alpine desert. &amp;nbsp;The slope is eroding. &lt;br /&gt;&lt;br /&gt;After a while I began asking my self, "why does that plant (weed?) grow there?" &amp;nbsp;I noticed that around the rocks that are a foot&amp;nbsp;around&amp;nbsp;lots of plants grow. but on the&amp;nbsp;barren&amp;nbsp;eroding slope nothing grows. &amp;nbsp;The dirt eroding down the hill get dammed up behind the rocks and forms a small flat spot where the plants grow.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-aLLbVF_LIUI/TlBM7azoxgI/AAAAAAAAADA/YPBoCRQQHDM/s1600/PlantsAndRocks.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/-aLLbVF_LIUI/TlBM7azoxgI/AAAAAAAAADA/YPBoCRQQHDM/s320/PlantsAndRocks.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The rocks also deflect the rain to the plants and keep the soil under the rock cooler and moist. &amp;nbsp;Our back patio has nice green grass between the flagstones for the same reason.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-oBIdkp4b_g4/TlBM_gB-RLI/AAAAAAAAADE/0zJ6WukLxq4/s1600/Microdams.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/-oBIdkp4b_g4/TlBM_gB-RLI/AAAAAAAAADE/0zJ6WukLxq4/s320/Microdams.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I have taken lots of the rocks that were along the bottom of the slope, and moved them up into the erosion gullies as little dams to hold back the dirt. &amp;nbsp;We will see how it looks next summer.&lt;br /&gt;&lt;br /&gt;P.S. In the spirit of getting many&amp;nbsp;synergistic&amp;nbsp;things done at once, I also got some good weight lifting in without the cost of a Spa.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-4463722332828541785?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/4463722332828541785/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=4463722332828541785' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/4463722332828541785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/4463722332828541785'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2011/08/permaculture-and-rocks-mico-dams.html' title='Permaculture and Rocks - Mico-dams'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-aLLbVF_LIUI/TlBM7azoxgI/AAAAAAAAADA/YPBoCRQQHDM/s72-c/PlantsAndRocks.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-7197382932718325202</id><published>2011-07-29T17:36:00.000-07:00</published><updated>2011-07-29T17:38:40.890-07:00</updated><title type='text'>On Not Watching TV</title><content type='html'>Sometimes some aspect of life can disappear and you don't even notice for a long while...&lt;br /&gt;&lt;br /&gt;A while back we stopped paying out Comcast bill. &amp;nbsp;They eventually shut us off, and a few weeks later some guy showed up and retrieved the cable boxes when I wasn't home. &lt;br /&gt;&lt;br /&gt;At some point after several weeks of no TV, I realized that the TV no longer worked!&lt;br /&gt;&lt;br /&gt;We still have internet and NetFlix, still have the HDTV in the basement for NetFlix BlueRay, and all the XBoxen, Wiii, etc. so it's not like we are unplugged. &amp;nbsp;We watch TV shows, but when we want to, on our schedule.&lt;br /&gt;&lt;br /&gt;So some thoughts are in order in regard to the great wasteland that is TV.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Wow, the house is quieter in the evenings.&amp;nbsp;Before,&amp;nbsp;there was&amp;nbsp;always&amp;nbsp;the TV in in the evenings and loud too.&lt;/li&gt;&lt;li&gt;Everyone is doing more interesting things, at a minimum on the computers instead where it is interactive activities.&lt;/li&gt;&lt;li&gt;The stress of TV is gone, let me explain: Most TV shows, if you get far away and listen to the voice tone instead of the actual words, are all people with tons of stress in their voices. &amp;nbsp;The 'reality' shows which&amp;nbsp;Weird&amp;nbsp;Al parodies so well, are all borderline psychotic people emoting about some&amp;nbsp;tragedy. &amp;nbsp;The predominant emotions on TV are stress, fear, violence, fright, anxiety and such.&lt;/li&gt;&lt;/ul&gt;It is probably 'writing on the wall' that my TV could disappear and I didn't even notice for a few weeks. &amp;nbsp;The networks are doomed.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-7197382932718325202?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/7197382932718325202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=7197382932718325202' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/7197382932718325202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/7197382932718325202'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2011/07/on-not-watching-tv.html' title='On Not Watching TV'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-7027452631696732766</id><published>2011-07-14T11:30:00.000-07:00</published><updated>2011-07-14T11:30:21.592-07:00</updated><title type='text'>On Raw Salad</title><content type='html'>So after reading a raw foods book, where they suggest you eat only live food, and another book by Art DeVany about paleofitness, I have been eating more salads.&lt;br /&gt;&lt;br /&gt;So I bought a organic salad mix of baby greens in a plastic box. &amp;nbsp;I didn't have any salad dressing, so I just ate from the box like the leaves were potato chips.&lt;br /&gt;&lt;br /&gt;Wow, each type of leaf has a unique flavor. &amp;nbsp;When you drown a salad in dressing, you miss what the actual salad tastes like!&lt;br /&gt;&lt;br /&gt;It sort of&amp;nbsp;surprises&amp;nbsp;your&amp;nbsp;tongue&amp;nbsp;when you put in a leaf, since you never know what a given leaf will taste like.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-7027452631696732766?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/7027452631696732766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=7027452631696732766' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/7027452631696732766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/7027452631696732766'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2011/07/on-raw-salad.html' title='On Raw Salad'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-951947591892510853</id><published>2011-07-08T21:06:00.000-07:00</published><updated>2011-07-08T21:06:47.482-07:00</updated><title type='text'>NetLib C++ bug fix in Advanced 3D Game Programming with DirectX 10.0</title><content type='html'>Ok,&lt;br /&gt;I'm using NetLib and got a packet to transmit and receive, but there was a crash.&lt;br /&gt;&lt;br /&gt;In QueueIn.cpp in&amp;nbsp;AddPacket the line&lt;br /&gt;&lt;blockquote&gt;pPacket = *d_packetsUnordered.begin();&lt;/blockquote&gt;Throws on the first packet.&lt;br /&gt;Just before that line you need...&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;if(d_packetsUnordered.size() &amp;gt; 0)&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;{&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;TF&lt;br /&gt;&lt;blockquote&gt;&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;&amp;nbsp;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-951947591892510853?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/951947591892510853/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=951947591892510853' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/951947591892510853'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/951947591892510853'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2011/07/netlib-c-bug-fix-in-advanced-3d-game.html' title='NetLib C++ bug fix in Advanced 3D Game Programming with DirectX 10.0'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-2078485804654784279</id><published>2011-06-10T11:46:00.000-07:00</published><updated>2011-06-10T11:46:27.773-07:00</updated><title type='text'>Notes on I2C and SSI bus implementation</title><content type='html'>A quick note:&lt;br /&gt;&lt;br /&gt;When you implement I2C and/or SSI you must implement timeouts and anit-lockup code.&lt;br /&gt;Both busses are driven with statements like&lt;br /&gt;&lt;br /&gt;while(some flag) &amp;nbsp;wait forever.&lt;br /&gt;&lt;br /&gt;And you can get locked up if there is a single clock glitch.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;void I2CResetLoopTimer(int i2cDeviceIdx)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; xI2CConfigHandle h = I2CDevices[i2cDeviceIdx];&lt;br /&gt;&amp;nbsp; h-&amp;gt;loopTimer = xTaskGetTickCount();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;int I2CHasError(int i2cDeviceIdx)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; xI2CConfigHandle h = I2CDevices[i2cDeviceIdx];&lt;br /&gt;&amp;nbsp; portTickType dt = xTaskGetTickCount() - h-&amp;gt;loopTimer;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; return dt &amp;gt; 200 ||&lt;br /&gt;&amp;nbsp; &amp;nbsp; I2C_GetFlagStatus(h-&amp;gt;i2cDevice, I2C_FLAG_TIMEOUT) ||&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; I2C_GetFlagStatus(h-&amp;gt;i2cDevice, I2C_FLAG_PECERR) ||&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; I2C_GetFlagStatus(h-&amp;gt;i2cDevice, I2C_FLAG_AF) ||&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; I2C_GetFlagStatus(h-&amp;gt;i2cDevice, I2C_FLAG_ARLO) ||&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; I2C_GetFlagStatus(h-&amp;gt;i2cDevice, I2C_FLAG_BERR);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;int I2CHasErrorAndClear(int i2cDeviceIdx)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; if(I2CHasError(i2cDeviceIdx))&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp; &amp;nbsp; I2CClearError(i2cDeviceIdx);&lt;br /&gt;&amp;nbsp; &amp;nbsp; return true;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; return false;&lt;br /&gt;}&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And an example loop.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;int WhileBusy(int i2cDeviceIdx)&lt;/div&gt;&lt;div&gt;{&lt;/div&gt;&lt;div&gt;&amp;nbsp; xI2CConfigHandle h = I2CDevices[i2cDeviceIdx];&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp; I2CResetLoopTimer(i2cDeviceIdx);&lt;/div&gt;&lt;div&gt;&amp;nbsp; while (I2C_GetFlagStatus(h-&amp;gt;i2cDevice, I2C_FLAG_BUSY))&lt;/div&gt;&lt;div&gt;&amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; if(I2CHasErrorAndClear(i2cDeviceIdx))&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; return false;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; portYIELD();&lt;/div&gt;&lt;div&gt;&amp;nbsp; }&lt;/div&gt;&lt;div&gt;&amp;nbsp; return true;&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;TF&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-2078485804654784279?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/2078485804654784279/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=2078485804654784279' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2078485804654784279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2078485804654784279'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2011/06/notes-on-i2c-and-ssi-bus-implementation.html' title='Notes on I2C and SSI bus implementation'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-1836270203106880159</id><published>2011-06-10T11:42:00.000-07:00</published><updated>2011-06-10T12:01:04.310-07:00</updated><title type='text'>I2C Reset on ST Microsystems Processors</title><content type='html'>So,&lt;br /&gt;You have a ST processor (e.g. STM32F103) and a I2C device. &amp;nbsp;If the device, bus, or processor gets a bit error in the I2C bus, it will lock up the bus.&lt;br /&gt;&lt;br /&gt;After trying many solutions, this one works...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;void I2C_ResetAndInit()&lt;br /&gt;{&lt;br /&gt;&lt;div&gt;/* This shuts off power to the I2C circuit on the processor. */&lt;br /&gt;I2C_DeInit(I2C1);&lt;br /&gt;&lt;br /&gt;RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);&lt;br /&gt;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);&lt;br /&gt;&lt;br /&gt;/* SCL &amp;nbsp;pin enable */&lt;br /&gt;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;&lt;br /&gt;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;&lt;br /&gt;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;&lt;br /&gt;GPIO_Init(GPIOB, &amp;amp;GPIO_InitStructure);&lt;br /&gt;&lt;br /&gt;/* SDA pin enable &amp;nbsp;*/&lt;br /&gt;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;&lt;br /&gt;GPIO_Init(GPIOB, &amp;amp;GPIO_InitStructure);&lt;br /&gt;&lt;br /&gt;I2C_StructInit(&amp;amp;I2C1_InitDef);&lt;br /&gt;// 400 khz.&lt;br /&gt;I2C1_InitDef.I2C_ClockSpeed = 100000;&lt;br /&gt;I2C_Init(I2C1, &amp;amp;I2C1_InitDef);&lt;br /&gt;&lt;br /&gt;I2C_Cmd(I2C1, ENABLE);&lt;br /&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And for the I2c Device out there on the bus...&lt;/div&gt;&lt;div&gt;Oh, we are using RTOS so that is the delayt and tick stuff.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;portTickType Baro_LastErrorMessageTime = 0;&lt;br /&gt;void BaroResetChip()&lt;br /&gt;{  &lt;br /&gt;if(xTaskGetTickCount() - Baro_LastErrorMessageTime &amp;gt; 10000)&lt;br /&gt;{&lt;br /&gt;Baro_LastErrorMessageTime = xTaskGetTickCount();&lt;br /&gt;mainMessagePrint(ROUTE_HALL, "Baro failed, reset.");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;I2CClearError(I2C_DEVICE_BARO);&lt;br /&gt;&lt;div&gt;// Turn the baro power off and then back on.&lt;br /&gt;// You DID put this in your design, right?&lt;br /&gt;// Also, many I2C chips have a reset line that will do the same thing.&lt;br /&gt;SetPwrBaro(0);&lt;br /&gt;vTaskDelay(3000);&lt;br /&gt;SetPwrBaro(1);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;I2C_ResetAndInit();&lt;br /&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In summary, the important pat is you must either reset or power cycle the I2C device, and you must use DeInit to power cycle the I2C internal device on the CPU.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;TF&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-1836270203106880159?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/1836270203106880159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=1836270203106880159' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1836270203106880159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1836270203106880159'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2011/06/i2c-reset-on-st-microsystems-processors.html' title='I2C Reset on ST Microsystems Processors'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-15868940902921437</id><published>2011-04-04T22:31:00.000-07:00</published><updated>2011-04-04T22:31:20.819-07:00</updated><title type='text'>XNA Steam side by side configuration</title><content type='html'>Quick Note:&lt;br /&gt;&lt;br /&gt;I had a side by side configuration error when trying to run my C# XNA Steam app on a clean machine.&lt;br /&gt;&lt;br /&gt;Short Answer: The problem was that my dll I wrote to mediate between XNA C# and unmanaged C++&lt;br /&gt;was compiled in debug mode instead of release mode.&lt;br /&gt;&lt;br /&gt;This happens because the VC redist package is for release only. &amp;nbsp;You can not redistribute the debug version.&lt;br /&gt;Once I recompile for release and moved the .dll and such into my steam release area it worked fine.&lt;br /&gt;&lt;br /&gt;TF&lt;br /&gt;&lt;br /&gt;P.S. I will be making the SteamLink source available to the Steam guys so they can give it out to developers.&lt;br /&gt;That will save tons of time for other people.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-15868940902921437?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/15868940902921437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=15868940902921437' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/15868940902921437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/15868940902921437'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2011/04/xna-steam-side-by-side-configuration.html' title='XNA Steam side by side configuration'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-3384491487452851704</id><published>2010-12-28T16:19:00.000-08:00</published><updated>2010-12-28T16:19:01.147-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='STM32F103 Reset System Interrupt Hard'/><title type='text'>STM32F103 System Reset</title><content type='html'>OK, a tough one to find.&lt;br /&gt;&lt;br /&gt;If you want to cause the processor to reset its self, you are looking for&amp;nbsp;&lt;b&gt;NVIC_SystemReset &lt;/b&gt;in the core_cm3.h file!&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-3384491487452851704?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/3384491487452851704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=3384491487452851704' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/3384491487452851704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/3384491487452851704'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2010/12/stm32f103-system-reset.html' title='STM32F103 System Reset'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-291179466049742354</id><published>2010-12-17T10:58:00.000-08:00</published><updated>2010-12-17T10:58:28.294-08:00</updated><title type='text'>STM32F103 SPI (SSI) Bus Code</title><content type='html'>&lt;span class="Apple-style-span" style="color: blue;"&gt;So,&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;The docs that come from ST Micro are pretty good as far as listing methods, and all the info is there. &amp;nbsp;The code examples that come with &amp;nbsp;the Standard Peripheral Library are nifty, but nowhere are there explanations of how things work. &amp;nbsp;The code examples all use Interrupts or DMA. &amp;nbsp;Those are nifty once everything works, but with a new board and chips one needs to be able to test things in a polling fashion. &amp;nbsp;Also we use RTOS.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;First, I have a struct for each SPI device, and use SPI1 for most devices, and SPI2 for a particular device that requires very frequent (6000 per second) access.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;typedef struct SSIConfigStruct {&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;// Arbitrary name of the device. e.g. "GYROS"&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;char name[32];&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;xSemaphoreHandle semaphore;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;SPI_InitTypeDef spiInitStruct;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;SPI_TypeDef * spiDevice;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;// The chip enable for the target slave device.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;// SPI chip enables are inverted.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;uint16_t GPIO_Pin;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;GPIO_TypeDef * GPIO_Port;&lt;br /&gt;} xSSIConfig;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;Each SPI bus has a lock semaphore to control acccess.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;And here are the globals...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;xSemaphoreHandle SSILock1;&lt;br /&gt;xSemaphoreHandle SSILockGyros;&lt;br /&gt;xSSIConfigHandle SSIDevices[SSI_DEVICE_COUNT];&lt;br /&gt;// All except gyros.&lt;br /&gt;SPI_InitTypeDef SPI1_InitStructure;&lt;br /&gt;// Just the gyros.&lt;br /&gt;SPI_InitTypeDef SPIGyros_InitStructure;&lt;br /&gt;unsigned char * ssi1Lockee = "Uninitialized";&lt;br /&gt;unsigned char * ssi2Lockee = "Uninitialized";&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;The Lockee pointers are set when a device gets selected and the lock is acquired so in debugging I know who did what.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;So initializing one of the SPI busses is like this..&lt;/span&gt;.&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp;ssi1Lockee = "Unused";&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; RCC_APB2Periph_GPIOB |&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; RCC_APB2Periph_AFIO |&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; RCC_APB2Periph_SPI1,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ENABLE);&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;// The general use SPI bus. SPI1&lt;br /&gt;&amp;nbsp;&amp;nbsp;vSemaphoreCreateBinary(SSILock1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_Init(GPIOA, &amp;amp;GPIO_InitStructure);&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI_StructInit(&amp;amp;SPI1_InitStructure);&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI1_InitStructure.SPI_Mode = SPI_Mode_Master;&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI1_InitStructure.SPI_NSS = SPI_NSS_Soft;&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI1_InitStructure.SPI_CPOL = SPI_CPOL_Low;&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI1_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;&lt;br /&gt;&amp;nbsp;&amp;nbsp;// of SPI_BaudRatePrescaler_64 results in a clock rate of 1.1 Mhz&lt;br /&gt;&amp;nbsp;&amp;nbsp;// (Measured with oscilloscope.)&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI1_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI_Init(SPI1 , &amp;amp;SPI1_InitStructure);&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI_Cmd(SPI1, ENABLE);&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;// The 3 gyros on their own private SPI bus. SPI2&lt;br /&gt;&amp;nbsp;&amp;nbsp;vSemaphoreCreateBinary(SSILockGyros);&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_Init(GPIOB, &amp;amp;GPIO_InitStructure);&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI_StructInit(&amp;amp;SPIGyros_InitStructure);&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPIGyros_InitStructure.SPI_Mode = SPI_Mode_Master;&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPIGyros_InitStructure.SPI_NSS = SPI_NSS_Soft;&lt;br /&gt;&amp;nbsp;&amp;nbsp;// of SPI_BaudRatePrescaler_16 results in a clock rate of 2.2 Mhz&lt;br /&gt;&amp;nbsp;&amp;nbsp;// (Measured with oscilloscope.)&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPIGyros_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI_Init(SPI2 , &amp;amp;SPIGyros_InitStructure);&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI_Cmd(SPI2, ENABLE);&lt;br /&gt;&amp;nbsp;&lt;br /&gt;(removed code ... initialize each sub device on the SPI bus ... )&lt;/blockquote&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;Notice that you first enable clocking to the IO ports and peripheral devices. &amp;nbsp;Not having clocks on save power on the chip. &amp;nbsp;Also, the chip enables are low asserted and hooked to various bits on the GPIOE port.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;Initializing a single device is like this...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp;// The RESET line on the PIN ASIC. Normally low, toggle high then low to reset&lt;br /&gt;&amp;nbsp;&amp;nbsp;// and start next sample. &amp;nbsp;Pin PE7&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_Init(GPIOE, &amp;amp;GPIO_InitStructure); &lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_WriteBit(GPIOE, GPIO_Pin_7, Bit_RESET);&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;SSIDevices[SSI_DEVICE_PNI11096] = &amp;amp;PNI11096SSIConfig;&lt;br /&gt;&amp;nbsp;&amp;nbsp;PNI11096SSIConfig.GPIO_Port = GPIOE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;PNI11096SSIConfig.GPIO_Pin = GPIO_Pin_11;&lt;br /&gt;&amp;nbsp;&amp;nbsp;strncpy_safe(PNI11096SSIConfig.name, "PNIC", 32);&lt;br /&gt;&amp;nbsp;&amp;nbsp;PNI11096SSIConfig.spiDevice = SPI1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;PNI11096SSIConfig.semaphore = SSILock1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI_StructInit(&amp;amp;PNI11096SSIConfig.spiInitStruct);&lt;br /&gt;&amp;nbsp;&amp;nbsp;PNI11096SSIConfig.spiInitStruct.SPI_DataSize = SPI_DataSize_8b;&lt;br /&gt;&amp;nbsp;&amp;nbsp;// TODO&lt;br /&gt;&amp;nbsp;&amp;nbsp;// Max is 1 MHz&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI_InitGPIOPin(&amp;amp;PNI11096SSIConfig);&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;The big secret here is that to change clock rate or between 8 bit and 16 bit requires that you disable the SPI bus, make the change, and enable the bus again.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;So the support routines look like this...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;// Delay loop is about 6 instructions per loop.&lt;br /&gt;void &lt;b&gt;SSI_Delay&lt;/b&gt;(int n)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;volatile int SPI_DelayCount;&lt;br /&gt;&amp;nbsp;&amp;nbsp;for(SPI_DelayCount=0; SPI_DelayCount &amp;lt; n; SPI_DelayCount++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;void &lt;b&gt;SPI_InitGPIOPin&lt;/b&gt;(xSSIConfigHandle h)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_InitStructure.GPIO_Pin = h-&amp;gt;GPIO_Pin;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_Init(GPIOE, &amp;amp;GPIO_InitStructure); &lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_WriteBit(h-&amp;gt;GPIO_Port, h-&amp;gt;GPIO_Pin, Bit_SET);&lt;br /&gt;}&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;// Make the device be the current device.&lt;br /&gt;void &lt;b&gt;SSI_SwitchTo&lt;/b&gt;(int deviceIdx, unsigned char * lockee)&lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;xSSIConfigHandle h = SSIDevices[deviceIdx];&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;if(h-&amp;gt;spiDevice == SPI1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;ssi1Lockee = lockee;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;else if(h-&amp;gt;spiDevice == SPI2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;ssi2Lockee = lockee;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI_Cmd(SPI1, DISABLE);&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI_DataSizeConfig(h-&amp;gt;spiDevice, h-&amp;gt;spiInitStruct.SPI_DataSize);&lt;br /&gt;&amp;nbsp;&amp;nbsp;// TODO - Set click divisor to get correct frequency.&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI_Cmd(SPI1, ENABLE);&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_ResetBits(h-&amp;gt;GPIO_Port, h-&amp;gt;GPIO_Pin);&lt;br /&gt;}&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;void &lt;b&gt;SSI_UnSwitch&lt;/b&gt;(int deviceIdx)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;xSSIConfigHandle h = SSIDevices[deviceIdx];&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_SetBits(h-&amp;gt;GPIO_Port, h-&amp;gt;GPIO_Pin);&lt;br /&gt;&amp;nbsp;&amp;nbsp;if(h-&amp;gt;spiDevice == SPI1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;ssi1Lockee = "None";&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;else if(h-&amp;gt;spiDevice == SPI2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;ssi2Lockee = "None";&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;volatile short ittibits;&lt;br /&gt;// Enables the device, sends data, waits for it to finish sending, gets results.&lt;br /&gt;// Disables the device after the read.&lt;br /&gt;unsigned short &lt;b&gt;SSI_SendDataAndWaitAndDone&lt;/b&gt;(int deviceIdx, unsigned short data)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;short ret;&lt;br /&gt;&amp;nbsp;&amp;nbsp;xSSIConfigHandle h = SSIDevices[deviceIdx];&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp;// Clear any latent recieved data just in case.&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;&amp;nbsp;SPI_I2S_ReceiveData (h-&amp;gt;spiDevice);&lt;/blockquote&gt;&lt;blockquote&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_ResetBits(h-&amp;gt;GPIO_Port, h-&amp;gt;GPIO_Pin);&lt;br /&gt;&amp;nbsp;&amp;nbsp;// 75Mhz / 6 cycles so this is a little under 1 microsecond.&lt;br /&gt;&amp;nbsp;&amp;nbsp;SSI_Delay(1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI_I2S_SendData (h-&amp;gt;spiDevice, data);&lt;br /&gt;&amp;nbsp;&amp;nbsp;while (SPI_I2S_GetFlagStatus(h-&amp;gt;spiDevice, SPI_I2S_FLAG_TXE) == RESET)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;portYIELD();&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;while (SPI_I2S_GetFlagStatus(h-&amp;gt;spiDevice, SPI_I2S_FLAG_RXNE) == RESET)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;portYIELD();&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;ret = SPI_I2S_ReceiveData (h-&amp;gt;spiDevice);&lt;br /&gt;&amp;nbsp;&amp;nbsp;// So we can debug the value.&lt;br /&gt;&amp;nbsp;&amp;nbsp;ittibits = ret;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_SetBits(h-&amp;gt;GPIO_Port, h-&amp;gt;GPIO_Pin);&lt;br /&gt;&amp;nbsp;&amp;nbsp;SSI_Delay(1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;return ret;&lt;br /&gt;}&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;// Enables the device, sends data, waits for it to finish sending, gets results.&lt;br /&gt;// Does NOT disable the device after the read.&lt;br /&gt;unsigned short &lt;b&gt;SSI_SendDataAndWaitAndNotDone&lt;/b&gt;(int deviceIdx, unsigned short data)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;unsigned short ret;&lt;br /&gt;&amp;nbsp;&amp;nbsp;xSSIConfigHandle h = SSIDevices[deviceIdx];&lt;br /&gt;&amp;nbsp;&amp;nbsp;ittibits = data;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI_I2S_ReceiveData (h-&amp;gt;spiDevice);&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;GPIO_ResetBits(h-&amp;gt;GPIO_Port, h-&amp;gt;GPIO_Pin);&lt;br /&gt;&amp;nbsp;&amp;nbsp;SSI_Delay(1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;SPI_I2S_SendData (h-&amp;gt;spiDevice, data);&lt;br /&gt;&amp;nbsp;&amp;nbsp;while (SPI_I2S_GetFlagStatus(h-&amp;gt;spiDevice, SPI_I2S_FLAG_TXE) == RESET)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;portYIELD();&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;while (SPI_I2S_GetFlagStatus(h-&amp;gt;spiDevice, SPI_I2S_FLAG_RXNE) == RESET)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;portYIELD();&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;ret = SPI_I2S_ReceiveData (h-&amp;gt;spiDevice);&lt;br /&gt;&amp;nbsp;&amp;nbsp;ittibits = ret;&lt;br /&gt;&amp;nbsp;&amp;nbsp;return ret;&lt;br /&gt;}&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;unsigned short &lt;b&gt;SSI_LockSendDataAndWaitAndDone&lt;/b&gt;(int deviceIdx, unsigned short data)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;xSSIConfigHandle h = SSIDevices[deviceIdx];&lt;br /&gt;&amp;nbsp;&amp;nbsp;unsigned short ret;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;xSemaphoreTake(h-&amp;gt;semaphore, portMAX_DELAY);&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;SPI_I2S_ReceiveData (h-&amp;gt;spiDevice);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;GPIO_ResetBits(h-&amp;gt;GPIO_Port, h-&amp;gt;GPIO_Pin);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 75Mhz / 6 cycles so this is a little under 1 microsecond.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;SSI_Delay(1);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;SPI_I2S_SendData (h-&amp;gt;spiDevice, data);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;while (SPI_I2S_GetFlagStatus(h-&amp;gt;spiDevice, SPI_I2S_FLAG_TXE) == RESET)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;portYIELD();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;while (SPI_I2S_GetFlagStatus(h-&amp;gt;spiDevice, SPI_I2S_FLAG_RXNE) == RESET)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;portYIELD();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;ret = SPI_I2S_ReceiveData (h-&amp;gt;spiDevice);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;// So we can debug the value.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;ittibits = ret;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;GPIO_SetBits(h-&amp;gt;GPIO_Port, h-&amp;gt;GPIO_Pin);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;SSI_Delay(1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;xSemaphoreGive(h-&amp;gt;semaphore);&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;return ret;&lt;br /&gt;}&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;// Enables the device, sends data, waits for it to finish sending, gets results.&lt;br /&gt;// Does NOT disable the device after the read.&lt;br /&gt;unsigned short &lt;b&gt;SSI_LockSendDataAndWaitAndNotDone&lt;/b&gt;(int deviceIdx, unsigned short data)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;xSSIConfigHandle h = SSIDevices[deviceIdx];&lt;br /&gt;&amp;nbsp;&amp;nbsp;unsigned short ret;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;xSemaphoreTake(h-&amp;gt;semaphore, portMAX_DELAY);&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;SPI_I2S_ReceiveData (h-&amp;gt;spiDevice);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;GPIO_ResetBits(h-&amp;gt;GPIO_Port, h-&amp;gt;GPIO_Pin);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;SSI_Delay(1);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;SPI_I2S_SendData (h-&amp;gt;spiDevice, data);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;while (SPI_I2S_GetFlagStatus(h-&amp;gt;spiDevice, SPI_I2S_FLAG_TXE) == RESET)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;portYIELD();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;while (SPI_I2S_GetFlagStatus(h-&amp;gt;spiDevice, SPI_I2S_FLAG_RXNE) == RESET)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;portYIELD();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;ret = SPI_I2S_ReceiveData (h-&amp;gt;spiDevice);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;ittibits = ret;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;xSemaphoreGive(h-&amp;gt;semaphore);&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;return ret;&lt;br /&gt;}&lt;/blockquote&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;TF&lt;/span&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-291179466049742354?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/291179466049742354/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=291179466049742354' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/291179466049742354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/291179466049742354'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2010/12/stm32f103-spi-ssi-bus-code.html' title='STM32F103 SPI (SSI) Bus Code'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-6617100020329149383</id><published>2010-10-27T14:19:00.000-07:00</published><updated>2010-10-28T09:00:28.872-07:00</updated><title type='text'>Transcendent Wonder</title><content type='html'>It's fall and it just snowed.&lt;br /&gt;&lt;br /&gt;So I had to get up in the dark and shovel the driveway, and the snow was so heavy I finally got out the snow blower. &amp;nbsp;So there I was feeling sorry for my self. &amp;nbsp;All this hard work and I just wanted to sleep.&lt;br /&gt;&lt;br /&gt;When I got done I came inside and started breakfast for the kids, and decided to do the dishes too.&lt;br /&gt;I was feeling even more angry, depressed, it's dark out, cold, no help...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;    I stopped and I looked&lt;br /&gt;    Each drop of water, unique.&lt;br /&gt;    Hands washing plates clean.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;All the anger and self pity evaporated.&lt;br /&gt;&lt;br /&gt;Transcendent Wonder.&lt;br /&gt;&lt;br /&gt;It's all around us all of the time.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-6617100020329149383?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/6617100020329149383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=6617100020329149383' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/6617100020329149383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/6617100020329149383'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2010/10/transcendent-wonder.html' title='Transcendent Wonder'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-2432711476814620656</id><published>2010-10-26T09:50:00.000-07:00</published><updated>2010-10-26T09:50:38.244-07:00</updated><title type='text'>The Depth of Children</title><content type='html'>So, this morning while getting ready for school, my 12 year old son asked,&lt;br /&gt;"Why do people have syntax in speaking when no other animal does."&lt;br /&gt;&lt;br /&gt;Wow, the other day we were talking about what is unique about humans and the main thing I told him was that we have syntax in language, and no other animal does.&lt;br /&gt;So then he looked it up on&amp;nbsp;Wikipedia&amp;nbsp;yesterday, "syntax", and then asked the question.&lt;br /&gt;So this morning we discussed evolution and how every trait is either useful or&amp;nbsp;vestigial.&lt;br /&gt;Syntax is useful&amp;nbsp;because&amp;nbsp;of very precise communication and survival.&lt;br /&gt;Tail bones&amp;nbsp;in humans are&amp;nbsp;vestigial.&lt;br /&gt;&lt;br /&gt;Then got onto the anthropic principle and how the world is the way it is because if it wasn't we wouldn't be here to ask why it is the way it is. Syntax is much like that. &amp;nbsp;If we didn't have syntax we wouldn't be able to think about thinking and ask such a question.&lt;br /&gt;&lt;br /&gt;Never underestimate the intelligence and depth of children!&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-2432711476814620656?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/2432711476814620656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=2432711476814620656' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2432711476814620656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2432711476814620656'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2010/10/depth-of-children.html' title='The Depth of Children'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-48085336039077738</id><published>2010-10-25T09:46:00.001-07:00</published><updated>2010-10-25T10:29:23.797-07:00</updated><title type='text'>How Cool are Wavelets</title><content type='html'>&lt;div style="text-align: left;"&gt;Ok, Todays topic, Wavelets.&lt;/div&gt;&lt;div&gt;Wavelets can be used to detect wave forms of some shape and frequency. &lt;/div&gt;&lt;div&gt;This is much like a poor man's FFT.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Wavlets work like this...&lt;/div&gt;&lt;div&gt;You have a 'template' wave shape that you are trying to detect.&lt;/div&gt;&lt;div&gt;For example a wave might look like this...&lt;/div&gt;&lt;img src="http://1.bp.blogspot.com/_tPxMCZtx__4/TMW14zemiuI/AAAAAAAAABA/pvodgw3Gi0g/s320/Wavlet1.png" style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 150px; height: 150px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5532027704790387426" /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is a kind of random wave shape but lets assume it is important to detect when this wave form happens in some data stream.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The incoming data stream might look like this...&lt;/div&gt;&lt;img src="http://1.bp.blogspot.com/_tPxMCZtx__4/TMW9jgfrHvI/AAAAAAAAABo/QF6LP7wLqZI/s320/WavletStream.png" style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 312px; height: 150px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5532036135010377458" /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The red wave to the right is the input data. &lt;/div&gt;&lt;div&gt;Hidden in there is the blue wave form with some noise.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What we do is convolute the input wave form with the wavelet.  By convolute we mean take each point in the wavelet and multiply it by the corresponding point in the input data stream and do that for every possible position along the input data stream.&lt;/div&gt;&lt;div&gt;Thus we 'scan' the input stream with the wavelet generating a correlation factor for each point along the input data stream.&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Like this...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;pre&gt;for i=0 to in.length&lt;br /&gt; sum[i] = 0;&lt;br /&gt; for k=0 to wavlet.length&lt;br /&gt;   sum[i] += in[i] * wavelet[k];&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Then the sum array will tell you how much a given point in the input correlates to the wavelet form.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you study this algorithm you will see that where the wavelet is high and the input is high you get a large positive number.  If the wavelet is negative and the input is negative you again get a large positive number.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If the input is zero and the wavelet is not zero &lt;/div&gt;&lt;div&gt;you still get zero, and also if the wavelet is zero and the input is not zero you still get zero.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If the input is the inverse of the wavelet then the&lt;/div&gt;&lt;div&gt; correlation will be negative.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A few notes: The wavelet must be normalized.  The ideal is that the peak wavelet value is 1.0.  Or you can make the integral of the wavelet be zero. It depends on what result you want.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The wavelet also has a frequency.  You can stretch&lt;/div&gt;&lt;div&gt;or shrink the wavelet length to detect different frequencies of the wave form.&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A specific frequency detector wavelet looks like this...&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img src="http://4.bp.blogspot.com/_tPxMCZtx__4/TMW5sLts8xI/AAAAAAAAABQ/5Z-pFyZMD0E/s320/WavletFrq.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5532031886004384530" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 312px; height: 150px; " /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This wavelet will detect a specific frequency.  The more cycles in the wave the narrower the&lt;/div&gt;&lt;div&gt; frequency detection.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This wavelet is a low pass filter...&lt;/div&gt;&lt;img src="http://4.bp.blogspot.com/_tPxMCZtx__4/TMW8HCu49QI/AAAAAAAAABY/2UrJpGnWYmU/s320/WavletLow.png" style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 312px; height: 150px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5532034546473170178" /&gt;&lt;div&gt;And this is a high pass filter...&lt;/div&gt;&lt;img src="http://1.bp.blogspot.com/_tPxMCZtx__4/TMW8XqbnPQI/AAAAAAAAABg/zLbKYzoLKZ8/s320/WavletHigh.png" style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 312px; height: 150px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5532034832007642370" /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The cool thing here is that the wavelet can detect a specific wave shape and timing without the more complex math of a complete FFT. Also with out knowing exact frequencies and such, you can detect a specific wave shape.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Very useful for heart beat detection, specific vibration modes, and many other uses.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There have been zillions of academic papers written analyzing specific wave shapes and exactly how they filter or detect frequencies.  But to use wavelets it is not necessary to understand all the theory.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;TF&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-48085336039077738?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/48085336039077738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=48085336039077738' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/48085336039077738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/48085336039077738'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2010/10/how-cool-are-wavelets.html' title='How Cool are Wavelets'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_tPxMCZtx__4/TMW14zemiuI/AAAAAAAAABA/pvodgw3Gi0g/s72-c/Wavlet1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-4956473294999138011</id><published>2010-04-30T12:57:00.000-07:00</published><updated>2011-12-19T10:59:03.029-08:00</updated><title type='text'>BMP085 C Code for ARM Processor</title><content type='html'>I have debugged this code for the BMP085 pressure and temperature sensor.&lt;br /&gt;&lt;br /&gt;(Note: I found this but do not yet have source:&amp;nbsp;&lt;a href="http://wmrx00.sourceforge.net/Arduino/BMP085-Calcs.pdf"&gt;More precise calcs&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;The examples in the data sheet assume an incorrect C operartor order.&lt;br /&gt;&lt;br /&gt;Also in Arduino kits the int is a short and a long is a 32 bit int.&lt;br /&gt;&lt;br /&gt;On my processor ( LM3S1607 ) an int is 32 bits.&lt;br /&gt;&lt;br /&gt;So in this code everything is an int or unsigned int.  Never short or unsigned short.&lt;br /&gt;&lt;br /&gt;Also Arduino example code assumes the oversampling to be 0 and here we can set it to higher resolution.&lt;br /&gt;&lt;br /&gt;The b3 = ... is where parenthesis are needed to get it right.&lt;br /&gt;&lt;br /&gt;Enjoy.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;int x1, x2, x3, b3, b5, b6, p;&lt;br /&gt;&lt;br /&gt;unsigned int b4, b7;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;x1 = ((BaroState.rawTemperature - Baro_ac6) * Baro_ac5) &amp;gt;&amp;gt; 15;&lt;br /&gt;x2 = (Baro_mc &amp;lt;&amp;lt; b5 =" x1" temperaturetenthc =" (b5"&amp;gt;&amp;gt; 4;&lt;br /&gt;&lt;br /&gt;b6 = b5 - 4000;&lt;br /&gt;x1 = (Baro_b2 * (b6 * b6 &amp;gt;&amp;gt; 12)) &amp;gt;&amp;gt; 11;&lt;br /&gt;x2 = Baro_ac2 * b6 &amp;gt;&amp;gt; 11;&lt;br /&gt;x3 = x1 + x2;&lt;br /&gt;// Error in the BMP085 spec sheet math.  Extra parens needed at the V's&lt;br /&gt;//    V                              V&lt;br /&gt;b3 = (((Baro_ac1 * 4 + x3) &amp;lt;&amp;lt; Baro_oss) + 2) &amp;gt;&amp;gt; 2;&lt;br /&gt;x1 = Baro_ac3 * b6 &amp;gt;&amp;gt; 13;&lt;br /&gt;x2 = (Baro_b1 * (b6 * b6 &amp;gt;&amp;gt; 12)) &amp;gt;&amp;gt; 16;&lt;br /&gt;x3 = ((x1 + x2) + 2) &amp;gt;&amp;gt; 2;&lt;br /&gt;b4 = (Baro_ac4 * (x3 + 32768)) &amp;gt;&amp;gt; 15;&lt;br /&gt;b7 = (BaroState.rawPressure - b3) * (50000 &amp;gt;&amp;gt; Baro_oss);&lt;br /&gt;p = b7 &amp;lt; x1 =" (p"&amp;gt;&amp;gt; 8) * (p &amp;gt;&amp;gt; 8);&lt;br /&gt;x1 = (x1 * 3038) &amp;gt;&amp;gt; 16;&lt;br /&gt;x2 = (-7357 * p) &amp;gt;&amp;gt; 16;&lt;br /&gt;BaroState.pressurePa = p + ((x1 + x2 + 3791) &amp;gt;&amp;gt; 4);&lt;br /&gt;NavState.baro = BaroState.pressurePa;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-4956473294999138011?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/4956473294999138011/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=4956473294999138011' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/4956473294999138011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/4956473294999138011'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2010/04/bmp085-c-code-for-arm-processor.html' title='BMP085 C Code for ARM Processor'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-5546321271605076031</id><published>2010-01-16T10:29:00.000-08:00</published><updated>2010-01-16T11:03:40.733-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='stellaris LM3S1607 internal clock SysCtlClockSet'/><title type='text'>LM3S1607 internal clock set</title><content type='html'>On the stellaris chips setting the clock up can be a challenge.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The prototype boards use external clock crystals.&lt;/div&gt;&lt;div&gt;The setup is like this...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To get the internal clock I use this...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;  SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_INT);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;TF&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;More...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Watch out! The internal oscillator on the LM3S1607 is only +- 30 % at 12 Mhz.&lt;/div&gt;&lt;div&gt;That means that UARTS will not work reliably at all.&lt;/div&gt;&lt;div&gt;So &lt;b&gt;thats&lt;/b&gt; why the eval board has a crystal on it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;TF&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-5546321271605076031?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/5546321271605076031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=5546321271605076031' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/5546321271605076031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/5546321271605076031'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2010/01/lm3s1607-internal-clock-set.html' title='LM3S1607 internal clock set'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-655344925221514436</id><published>2010-01-07T09:19:00.001-08:00</published><updated>2010-01-07T09:34:53.896-08:00</updated><title type='text'>UART1 on LM3S9B92</title><content type='html'>Ok,&lt;div&gt;I just spent 2 days hammering away at getting UART1 to put out a signal on the TI LM3S9B92-B eval board.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The sample code called hello.c talks to UART0 and works fine.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you try to switch to UART1 or UART2 it does not work.&lt;/div&gt;&lt;div&gt;SO I extracted the driverlib calls out to an easily switchable linear piece of code, like this...&lt;/div&gt;&lt;div&gt;(The blog post code mangles the C code a bit.  The for loops are munged.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;int&lt;/div&gt;&lt;div&gt;main(void)&lt;/div&gt;&lt;div&gt;{&lt;/div&gt;&lt;div&gt;    int uartIdx = 1;&lt;/div&gt;&lt;div&gt;    volatile unsigned long i;&lt;/div&gt;&lt;div&gt;    &lt;/div&gt;&lt;div&gt;    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |&lt;/div&gt;&lt;div&gt;                       SYSCTL_XTAL_16MHZ);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;    if(uartIdx == 0)&lt;/div&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);&lt;/div&gt;&lt;div&gt;      GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);&lt;/div&gt;&lt;div&gt;      SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);&lt;/div&gt;&lt;div&gt;      UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,&lt;/div&gt;&lt;div&gt;                            (UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE |&lt;/div&gt;&lt;div&gt;                             UART_CONFIG_WLEN_8));    &lt;/div&gt;&lt;div&gt;    } &lt;/div&gt;&lt;div&gt;    else&lt;/div&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);&lt;/div&gt;&lt;div&gt;      GPIOPinTypeUART(GPIO_PORTD_BASE, GPIO_PIN_2 | GPIO_PIN_3);&lt;/div&gt;&lt;div&gt;      SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);&lt;/div&gt;&lt;div&gt;      UARTConfigSetExpClk(UART1_BASE, ROM_SysCtlClockGet(), 115200,&lt;/div&gt;&lt;div&gt;                            (UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE |&lt;/div&gt;&lt;div&gt;                             UART_CONFIG_WLEN_8));  &lt;/div&gt;&lt;div&gt;      }&lt;/div&gt;&lt;div&gt;  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;    for(i=0; i&lt;100000;&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;    //&lt;/div&gt;&lt;div&gt;    while(1)&lt;/div&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;      if(uartIdx == 0)&lt;/div&gt;&lt;div&gt;      {&lt;/div&gt;&lt;div&gt;        UARTCharPut(UART0_BASE, 'K');&lt;/div&gt;&lt;div&gt;      }&lt;/div&gt;&lt;div&gt;      else&lt;/div&gt;&lt;div&gt;      {&lt;/div&gt;&lt;div&gt;        UARTCharPut(UART1_BASE, 'K');&lt;/div&gt;&lt;div&gt;      }&lt;/div&gt;&lt;div&gt;      for(i=0; i&lt;100000; i =" i"&gt;      {&lt;/div&gt;&lt;div&gt;      }&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But UART1 was stubbornly silent.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here is the corrected code, notice that I have to explicitly set the pins up...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;int&lt;/div&gt;&lt;div&gt;main(void)&lt;/div&gt;&lt;div&gt;{&lt;/div&gt;&lt;div&gt;    int uartIdx = 1;&lt;/div&gt;&lt;div&gt;    volatile unsigned long i;&lt;/div&gt;&lt;div&gt;    &lt;/div&gt;&lt;div&gt;    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |&lt;/div&gt;&lt;div&gt;                       SYSCTL_XTAL_16MHZ);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;    if(uartIdx == 0)&lt;/div&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);&lt;/div&gt;&lt;div&gt;      GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);&lt;/div&gt;&lt;div&gt;      SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);&lt;/div&gt;&lt;div&gt;      UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,&lt;/div&gt;&lt;div&gt;                            (UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE |&lt;/div&gt;&lt;div&gt;                             UART_CONFIG_WLEN_8));    &lt;/div&gt;&lt;div&gt;    } &lt;/div&gt;&lt;div&gt;    else&lt;/div&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);&lt;/div&gt;&lt;div&gt;      GPIOPinTypeUART(GPIO_PORTD_BASE, GPIO_PIN_2 | GPIO_PIN_3);&lt;/div&gt;&lt;div&gt;      SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);&lt;/div&gt;&lt;div&gt;      UARTConfigSetExpClk(UART1_BASE, ROM_SysCtlClockGet(), 115200,&lt;/div&gt;&lt;div&gt;                            (UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE |&lt;/div&gt;&lt;div&gt;                             UART_CONFIG_WLEN_8));  &lt;/div&gt;&lt;div&gt;      &lt;/div&gt;&lt;div&gt;&lt;b&gt;      GPIOPinConfigure(GPIO_PD2_U1RX);&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;      GPIOPinConfigure(GPIO_PD3_U1TX);&lt;/b&gt;&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;    for(i=0; i&lt;100000;i++&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;    //&lt;/div&gt;&lt;div&gt;    while(1)&lt;/div&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;      if(uartIdx == 0)&lt;/div&gt;&lt;div&gt;      {&lt;/div&gt;&lt;div&gt;        UARTCharPut(UART0_BASE, 'K');&lt;/div&gt;&lt;div&gt;      }&lt;/div&gt;&lt;div&gt;      else&lt;/div&gt;&lt;div&gt;      {&lt;/div&gt;&lt;div&gt;        UARTCharPut(UART1_BASE, 'K');&lt;/div&gt;&lt;div&gt;      }&lt;/div&gt;&lt;div&gt;      for(i=0; i&lt;100000;i&gt;      {&lt;/div&gt;&lt;div&gt;      }&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I think what is happening is that the in circuit debugger sets up the UART0 since that is used often in sample code.  None of the example code shows this solution.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Any way, I hope I have saved someone some time.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;TF&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;P.S. The signals out of the chip are inverted from standard RS232.  It is expected that your circuit will use drivers that convert the 0 to 3 volt TTL output to inverted -5 to + 5 volt RS232.&lt;/div&gt;&lt;div&gt;Thus if you directly wire a DB9 connector to a chip port and then into a PC serial port, it will not work.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-655344925221514436?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/655344925221514436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=655344925221514436' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/655344925221514436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/655344925221514436'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2010/01/uart1-on-lm3s9b92.html' title='UART1 on LM3S9B92'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-3798946366327410882</id><published>2009-11-20T13:35:00.000-08:00</published><updated>2009-11-23T14:12:47.600-08:00</updated><title type='text'>How Not To Make A Corporate Web Site</title><content type='html'>Ok, Time to blow off some steam.&lt;br /&gt;&lt;br /&gt;I think I have found the worst large corporation web sit there is.&lt;br /&gt;www.motorola.com&lt;br /&gt;&lt;br /&gt;What I was trying to do is simply find the manual for a Motorola XTS 5000 portable radio so I can hook it up to a PPP serial port on my Vista laptop.&lt;br /&gt;&lt;br /&gt;Sounds easy, huh?&lt;br /&gt;&lt;br /&gt;Well I tried the obvious, I googled Motorola XTS 5000 manual.&lt;br /&gt;All the results are for very unsafe web sites for manuals, none of which actually have the manuals.&lt;br /&gt;&lt;br /&gt;(Annoyed)&lt;br /&gt;&lt;br /&gt;A few links were to www.motorola.com, but all actual documents were just marketing brochures with no details.&lt;br /&gt;&lt;br /&gt;Their search function is so broken as to be nearly useless.&lt;br /&gt;&lt;br /&gt;(Anger level rising, 1 hour wasted)&lt;br /&gt;&lt;br /&gt;I finally called support and was told that all those manuals are on &lt;a href="http://www.motorola.com/Business/US-EN/Business+Solutions"&gt;Solutions - Motorola USA&lt;/a&gt;&lt;br /&gt;though "solutions" was obviously used as a euphemism for "marketing".&lt;br /&gt;But I would need to register to get an online acocunt and it would take two days.&lt;br /&gt;&lt;br /&gt;So I went to the site to sign up.  Wow, I think the signup form was designed by committee  where any field that was suggested was put in.&lt;br /&gt;&lt;br /&gt;Ok, this is silly.  All I wanted was to find an online manual for a radio.  Instead I got a process that would make passage of Obama's Medical Fiasco look easy.&lt;br /&gt;&lt;br /&gt;So while I waste two work days waiting for a simple piece of information, I noticed that there is a feed back email address.  Ohhhh, nifty.  So I careful write a short email about the shortcomings of the site.  Yup, you guessed it, the email bounced.&lt;br /&gt;&lt;br /&gt;So If it wasn't for the fact that my job requires that I get this software written...&lt;br /&gt;&lt;br /&gt;Ok, I'm done.  All better now.&lt;br /&gt;&lt;br /&gt;Oh, and let me theorize how the web site got this way...&lt;br /&gt;All the CXX managers of Motorola fought over getting their pet project in, and the web designer inside Motorola was ignored.  Nobody any where the top of the organization has ever actually used the site to try to do anything remotely like what a customer would do.  The web site is obviously organized by someone who is thinking about what they want the customer to see, and has no idea at all about what the &lt;span style="font-weight: bold;"&gt;customer actually wants&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;TF&lt;br /&gt;&lt;br /&gt;Three days later, after the weekend, yet another hurdle to cross.&lt;br /&gt;&lt;blockquote&gt;This is regarding your account with us.  Will you be reselling our products?  Or will it be for your own company use?&lt;br /&gt;If for company use than please state you are taxable.  If for resell then fill out the attached tax cert and fax back&lt;br /&gt;to NNN-NNN-NNNN&lt;/blockquote&gt;&lt;br /&gt;Aaaaaargh!&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-3798946366327410882?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/3798946366327410882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=3798946366327410882' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/3798946366327410882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/3798946366327410882'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2009/11/how-not-to-make-corporate-web-site.html' title='How Not To Make A Corporate Web Site'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-1989310736251516462</id><published>2009-10-20T11:58:00.001-07:00</published><updated>2009-10-20T12:14:29.715-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C# Serial Port COM names list'/><title type='text'>COM Port Listing in C#</title><content type='html'>Ok, here is the problem.&lt;br /&gt;How does one get a listing of COM ports in C# ?&lt;br /&gt;&lt;br /&gt;The short answer is...&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  String[] portNames = System.IO.Ports.SerialPort.GetPortNames();&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Like most short answers it is correct but not useful.&lt;br /&gt;The resulting list is a series of entries like "COM14". In my application I want the&lt;br /&gt;list to have the long port description like "Prolific USB-to-Serial Bridge (COM16)"&lt;br /&gt;&lt;br /&gt;This is tricky.  There can be regular serial ports and there can be USB dongles with serial ports.&lt;br /&gt;&lt;br /&gt;So what you do instead is first list the ports and make a list of them with both the simple name&lt;br /&gt;and a friendly name that are the same.&lt;br /&gt;Then you look through the plug n play devices for COM ports and get the Name from that.&lt;br /&gt;Like this...&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;using System.Management;&lt;br /&gt;using System.IO;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Then ...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;        private void SetupCOMPortInformation()&lt;br /&gt;        {&lt;br /&gt;            String[] portNames = System.IO.Ports.SerialPort.GetPortNames();&lt;br /&gt;            foreach (String s in portNames)&lt;br /&gt;            {&lt;br /&gt;                // s is like "COM14"&lt;br /&gt;                COMPortInfo ci = new COMPortInfo();&lt;br /&gt;                ci.portName = s;&lt;br /&gt;                ci.friendlyName = s;&lt;br /&gt;                ComPortInformation.Add(ci);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            String[] usbDevs = GetUSBCOMDevices();&lt;br /&gt;            foreach (String s in usbDevs)&lt;br /&gt;            {&lt;br /&gt;                // Name will be like "USB Bridge (COM14)"&lt;br /&gt;                int start = s.IndexOf("(COM") + 1;&lt;br /&gt;                if (start &gt;= 0)&lt;br /&gt;                {&lt;br /&gt;                    int end = s.IndexOf(")", start + 3);&lt;br /&gt;                    if (end &gt;= 0)&lt;br /&gt;                    {&lt;br /&gt;                        // cname is like "COM14"&lt;br /&gt;                        String cname = s.Substring(start, end - start);&lt;br /&gt;                        for (int i = 0; i &lt; ComPortInformation.Count; i++)&lt;br /&gt;                        {&lt;br /&gt;                            if (ComPortInformation[i].portName == cname)&lt;br /&gt;                            {&lt;br /&gt;                                ComPortInformation[i].friendlyName = s;&lt;br /&gt;                            }&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static string[] GetUSBCOMDevices()&lt;br /&gt;        {&lt;br /&gt;            List&lt;string&gt; list = new List&lt;string&gt;();&lt;br /&gt;&lt;br /&gt;            ManagementObjectSearcher searcher2 = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity");&lt;br /&gt;            foreach (ManagementObject mo2 in searcher2.Get())&lt;br /&gt;            {&lt;br /&gt;                string name = mo2["Name"].ToString();&lt;br /&gt;                // Name will have a substring like "(COM12)" in it.&lt;br /&gt;                if (name.Contains("(COM"))&lt;br /&gt;                {&lt;br /&gt;                    list.Add(name);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            // remove duplicates, sort alphabetically and convert to array&lt;br /&gt;            string[] usbDevices = list.Distinct().OrderBy(s =&gt; s).ToArray();&lt;br /&gt;            return usbDevices;&lt;br /&gt;        }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And we need the list element class...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public class COMPortInfo&lt;br /&gt;{&lt;br /&gt;  public String portName;&lt;br /&gt;  public String friendlyName;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There you are.&lt;br /&gt;&lt;br /&gt;Oh, and as extra credit.  This code lets you list every possible Management class.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;      private static void ListAllManagementClasses()&lt;br /&gt;      {&lt;br /&gt;          string cimRoot = "root\\";&lt;br /&gt;          ManagementClass nsClass = new ManagementClass(&lt;br /&gt;              new ManagementScope(@"root"),&lt;br /&gt;              new ManagementPath("__namespace"),&lt;br /&gt;              null);&lt;br /&gt;          foreach (ManagementObject ns in nsClass.GetInstances())&lt;br /&gt;          {&lt;br /&gt;              try&lt;br /&gt;              {&lt;br /&gt;                  Console.WriteLine(cimRoot + ns["Name"].ToString());&lt;br /&gt;                  ManagementClass newClass = new ManagementClass(cimRoot + ns["Name"].ToString());&lt;br /&gt;                  EnumerationOptions options = new EnumerationOptions();&lt;br /&gt;                  options.EnumerateDeep = true; // set to false if only the root classes are needed&lt;br /&gt;                  ManagementObjectCollection moc = newClass.GetSubclasses(options);&lt;br /&gt;                  foreach (ManagementObject o in moc)&lt;br /&gt;                  {&lt;br /&gt;                      if (o["__SuperClass"] == null)&lt;br /&gt;                          Console.WriteLine(o["__Class"]);&lt;br /&gt;                      else&lt;br /&gt;                          Console.WriteLine("\t" + o["__Class"]);&lt;br /&gt;                  }&lt;br /&gt;              }&lt;br /&gt;              catch (Exception ex)&lt;br /&gt;              {&lt;br /&gt;                  Console.WriteLine("Exception: " + ex.Message);&lt;br /&gt;              }&lt;br /&gt;          }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-1989310736251516462?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/1989310736251516462/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=1989310736251516462' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1989310736251516462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1989310736251516462'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2009/10/com-port-listing-in-c.html' title='COM Port Listing in C#'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-9082140733496985079</id><published>2009-08-20T08:24:00.000-07:00</published><updated>2009-08-20T12:57:16.309-07:00</updated><title type='text'>SATA RAID</title><content type='html'>Ok, for a compter game we are working on we need to record full HDMI video to make a marketing trailer. My current computer could not handle it at all.&lt;br /&gt;&lt;br /&gt;First the math: HDTV is 1290 x 1080 at 24 frames per second.&lt;br /&gt;That works out to 1.4 MPixels at 3 bytes per pixel is 100 MB per second.&lt;br /&gt;But there is also sound and some other overhead.&lt;br /&gt;&lt;br /&gt;So we went to NewEgg and bought parts:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;RAIDMAX SAGITTA 2 ATX-928WB Black case.  (Cool blue lights!)&lt;/li&gt;&lt;li&gt;ECS Black Series A790GXM-AD3 AM3 AMD 790GX HDMI ATX AMD Motherboard&lt;/li&gt;&lt;li&gt;AMD Phenom II x4 955 Black Edition Deneb 3.2 Ghz AM3 socket Quad-Core CPU&lt;/li&gt;&lt;li&gt;6 GB Ram&lt;/li&gt;&lt;li&gt;4 SATA Western Digital Caviar 160 GB Drives&lt;/li&gt;&lt;li&gt;Vista Home Premium 64 Bit&lt;/li&gt;&lt;li&gt;DVD SATA Drive&lt;/li&gt;&lt;li&gt;A Screen 22" wide screen&lt;/li&gt;&lt;li&gt;RAIDMAX 630W Power supply (More nifty blue lights)&lt;/li&gt;&lt;li&gt;Silver Thermal Past (not needed)&lt;/li&gt;&lt;li&gt;Cables etc.&lt;/li&gt;&lt;/ul&gt;The total was 1005.34 USD&lt;br /&gt;&lt;br /&gt;We also have a BlackMagic Intensity Pro for 200 USD.  This is a HDMI video grabber card and claims to be able to suck up full HDMI video.&lt;br /&gt;&lt;br /&gt;So it all showed up in about 3 days.  Lots of boxes.&lt;br /&gt;&lt;br /&gt;We put it all together.&lt;br /&gt;&lt;br /&gt;Then configured it in the BIOS for RAID 5.  That was a mistake. RAID 5 means that 3 of the 4 disks are used in parallel for reads and writes, and one is used for parity error correction.  This makes it more reliable.  After all the install and config, we put in the disk speed test program that came with the Intensity Pro, and we were getting about 350 MB per second read, but only about 50 MB/Sec write.  It would never do for what we needed.&lt;br /&gt;&lt;br /&gt;(I think the parity generation was slowing it down.)&lt;br /&gt;&lt;br /&gt;So...&lt;br /&gt;&lt;br /&gt;We reconfigured for RAID 0 with all four disks.  This uses all 4 disks in parallel for reads and writes.  After a complete reinstall of Vista etc.  we ran the disk test again.&lt;br /&gt;&lt;br /&gt;450 MB/Sec read &lt;span style="font-weight: bold;"&gt;and&lt;/span&gt; write.&lt;br /&gt;&lt;br /&gt;Smokin'&lt;br /&gt;&lt;br /&gt;This box is amazing.  The click and open on programs is almost instantaneous.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-9082140733496985079?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/9082140733496985079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=9082140733496985079' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/9082140733496985079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/9082140733496985079'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2009/08/sata-raid.html' title='SATA RAID'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-5103375655029500187</id><published>2009-08-11T13:28:00.000-07:00</published><updated>2009-08-13T11:05:00.683-07:00</updated><title type='text'>XNA Screen Projection</title><content type='html'>In XNA there is a method,&lt;br /&gt;&lt;br /&gt;Vector3 GraphicsDevice.Viewport.Project(Vector3 source, Matrix projection, Matrix view, Matrix world)&lt;br /&gt;&lt;br /&gt;that converts a world point to screen coordinates.&lt;br /&gt;&lt;br /&gt;The return value is a Vector3.  The X and Y is the screen location of the point.  It may not be&lt;br /&gt;within the GraphicsDevice.Viewport if the object is "off screen".&lt;br /&gt;&lt;br /&gt;One point of possible confusion is the Z part of the return value.  It is the depth into the Z buffer.&lt;br /&gt;Your projection matrix has a near and far plane.  A Z value of 0 is right on the far plane and is very far away into the screen.  A Z value of 1 is a point near the observer, right on the screen plane.&lt;br /&gt;&lt;br /&gt;A value of 0.5 would be half way between the far and near planes.&lt;br /&gt;&lt;br /&gt;If the Z value is greater than one then the point is &lt;span style="font-weight: bold;"&gt;behind&lt;/span&gt; the observer.&lt;br /&gt;&lt;br /&gt;After calling Project, you should check the Z value and if it is greater than 1 then don't draw anything.&lt;br /&gt;&lt;br /&gt;Note: if the Z value is &gt; 1 then that means that X and Y must be negated to figure out where the object is relative to the screen. This is important if you are doing a "Mario Smash Bros." style arrow that points off screen at an object that has flown off the edge.  But Smash Bros has it easy because no objects ever can get behind the observer.&lt;br /&gt;&lt;br /&gt;The reason that X and Y have to be negated is simple.  Imagine that the object is behind your head while you are looking at the screen.  Draw a line from the object, through your head, to the screen.  That is the screen location of the object.&lt;br /&gt;&lt;br /&gt;Note: UnProject is a method that does the inverse of Project. It converts a screen location (don't forget the Z part) to world space.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-5103375655029500187?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/5103375655029500187/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=5103375655029500187' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/5103375655029500187'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/5103375655029500187'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2009/08/xna-screen-projection.html' title='XNA Screen Projection'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-5220704786580065830</id><published>2009-07-10T13:50:00.000-07:00</published><updated>2009-07-10T14:16:20.086-07:00</updated><title type='text'>The Easy Programming Allusion</title><content type='html'>&lt;span style="font-weight: bold;"&gt;The Utopian Requirement&lt;/span&gt;&lt;br /&gt;On many project, I have seen the following logic...&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Lets have a easy scripting language or visual programming lanuge so non-programmers can customize the system.&lt;/li&gt;&lt;li&gt;We currently have to have programmers put in custom code for each customer's need and it is expensive.&lt;/li&gt;&lt;li&gt;We'll let the analyst at the customer's company do the change instead so it is easy and inexpensive.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;The Reality of Programming&lt;/span&gt;&lt;br /&gt;What is wrong with this picture?&lt;br /&gt;&lt;br /&gt;There are two types of changes to systems, &lt;span style="font-weight: bold;"&gt;configuration &lt;/span&gt;parameters, and &lt;span style="font-weight: bold;"&gt;code&lt;/span&gt;. &lt;br /&gt;A configuration parameter is usually a single number or setting that has a very limited set of valid values.  For example the department names in a company.  Some programmer has thought out in advance what all the possible valid values will be and designed the program to handle them.&lt;br /&gt;The second type of change is the one that causes the most trouble.  It is a change in the logic and processing of the program.  For example, maybe a 'if' statement that then calls any method available in the program to do processing.  Such changes can bring down the whole house of cards that is the program.&lt;br /&gt;Programmers deal with this by knowing the system well, making changes and debugging and testing.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Flaw&lt;/span&gt;&lt;br /&gt;The desire of management is to make such changes easy for a non-programmer.  But there is a basic contradiction here.  They want a person that does not know the code well, to make the change and not thoroughly test the whole system for interactions.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Reality&lt;/span&gt;&lt;br /&gt;What happens in the real world of product roll out, customer complaints, and emergency fixes to save the sales reps. account, is that the customer quickly gets the application into a state where is will not run, and then a programmer from the company ends up making the change, only now it is some 'scripting language' that is less flexible and powerful than the native language of the application.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Exception&lt;/span&gt;&lt;br /&gt;There is one exception in the real world to this logic, Excel.&lt;br /&gt;Excel is the most widely used programming language in the world and is used mostly by non-programmers. &lt;br /&gt;&lt;br /&gt;Why does this exception exits?&lt;br /&gt;Because Excel spreadsheet language is a highly domain specific language in it's simple form.  It lets you do simple math on cells.  There is no sequential programming being done, no 'if' statements, and a highly limited and sanitized method set.  If you make a mistake it tends to be located in exactly the cell you are editing.&lt;br /&gt;Then Excel has deeper programming constructs which most users never use.  Thus in some ways it is not being used as a programming language so much as simply customizing settings on cells, which are simple math.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Secret Solution&lt;/span&gt;&lt;br /&gt;There is a sweet spot of customization where the user is not programming, but simply customizing settings.  If you can reduce your customers job to 'configuration' then you win.&lt;br /&gt;&lt;br /&gt;So here is Keene's Rule of Customization:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;"Only let your customer configure."&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-5220704786580065830?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/5220704786580065830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=5220704786580065830' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/5220704786580065830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/5220704786580065830'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2009/07/easy-programming-allusion.html' title='The Easy Programming Allusion'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-2695546648674556260</id><published>2009-06-30T15:11:00.000-07:00</published><updated>2009-06-30T15:52:24.481-07:00</updated><title type='text'>Wrong Science, Write Answer, Wrong Execution</title><content type='html'>Congress is soon to pass a climate bill.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Wrong Science ?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;The climate debate and the science behind it is inconclusive.  On one side is the view the we create global warming by emitting CO2 and should stop it before the climate goes haywire and we have a disaster.&lt;br /&gt;&lt;br /&gt;The evidence to support Global Warming is fairly good, and in some areas is the current best science we have.  That does not make it correct and also the debate is not over.  When the debate is over then science has stopped and there is nothing more to discover.&lt;br /&gt;&lt;br /&gt;On the other side is the belief that Global Warming is not happening, or if it is, it is not our fault. The science for that point of view is also fairly good.&lt;br /&gt;&lt;br /&gt;The data about global climate is buried under so many layers of politics, dogma, academic reputations and such, that even reading the raw scientific papers does not arrive at any clear conclusion.&lt;br /&gt;&lt;br /&gt;So lets make a big assumption, that the whole Global Warming thing is one big mistake and hoax.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Write Answer&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;Ok, so then why cut carbon emissions, and do the economically painful, switch to non fossil fuels?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Firstly, the USA is currently shoveling cash at unbelievable rates at other nations to buy their oil.  This is unsustainable from any point of view. (Yeah &lt;a href="http://www.pickensplan.com/act/"&gt;Pickens Plan&lt;/a&gt;!) We will go bankrupt as a nation trying to buy foreign energy.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Second, &lt;a href="http://www.theoildrum.com/"&gt;The oil is running out&lt;/a&gt;.  We are just about out of 'Easy Oil' and as oil becomes more scarce, the price will be come increasingly volatile.  As oil becomes harder to get, the funds to research and build a non-oil base infrastructure will not be available.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Third, The environment (not the climate) is damaged by fossil fuel burning, starting with the&lt;span style="text-decoration: underline;"&gt; &lt;/span&gt;&lt;a href="http://www.scientificamerican.com/blog/60-second-science/post.cfm?id=clean-air-equals-longer-life-study-2009-01-21"&gt;lungs of Humans&lt;/a&gt;.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Fourth, Oil is used to make plastics and fertilizer, not just for energy. The world food supply and much our modern junk we buy at WalMart is dependent on oil. It does not need to be.  Fertilizer can be made from &lt;a href="http://windnh3.blogspot.com/"&gt;air and electricity&lt;/a&gt;. Plastics are the difficult one, and rubber for tires.  That might be a far better use of oil.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Wrong Execution&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;So hooray for Obama and the climate bill.  It forces a reduction in fossil fuel use and dependence on foreign oil.&lt;br /&gt;&lt;br /&gt;And now for the main point (drum roll please)&lt;br /&gt;&lt;br /&gt;The massive tax that the new climate bill represents $175 per household, with 105,480,101 households in the USA so that would be 18 billion dollars.   There has been absolutely no talk about how the fees collected as 'carbon taxes' would be spent. There has also been no talk about how much money the carbon credits would rais for the government.  The 18 billion dollar estimate is the best I can do for now.  Maybe it is more like a trillion dollars?  Who knows?  It does not get talked about.&lt;br /&gt;&lt;br /&gt;Not only that, there are zillions of loopholes in the bill so that the major emmiters of carbon won't suffer too much.  So who is going to suffer if we are to actualy reduce carbon emissions?  I bet it will be the middle class, as usual.&lt;br /&gt;&lt;br /&gt;My crystal ball tells me that the money will go to social spending.&lt;br /&gt;&lt;br /&gt;The correct answer should be to earmark ALL the money gathered from carbon sin taxes to alternate energy.&lt;br /&gt;&lt;br /&gt;Could you imagine what 18 billion dollars of research into algae oil would do?&lt;br /&gt;&lt;br /&gt;TF&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Footnote: The down side...&lt;br /&gt;Obama's climate bill will bankrupt the nation, while spending the money on 'lets be happy' programs.  This will result in an economy with no money to change over to alternate energy, an no time to research alternatives before the oil runs out, leaving us in poverty and despair.  Nations in poverty have no desire to help the environment.  Conclusion: Obama's climate bill will be the worst thing ever for the climate.&lt;br /&gt;&lt;br /&gt;Go Google 'The law of unintended consequences.'&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-2695546648674556260?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/2695546648674556260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=2695546648674556260' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2695546648674556260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2695546648674556260'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2009/06/wrong-science-write-answer-wrong.html' title='Wrong Science, Write Answer, Wrong Execution'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-6241377768934743716</id><published>2009-06-12T12:03:00.000-07:00</published><updated>2009-06-30T15:11:09.257-07:00</updated><title type='text'>What is 1 + 1?</title><content type='html'>&lt;ul&gt;&lt;li&gt;A five year old: two&lt;/li&gt;&lt;li&gt;A mathematician: That is arbitrary symbol system and unless I know which system you are using the answers are infinite.&lt;/li&gt;&lt;li&gt;A Physicist: 1.95 +- 0.01&lt;/li&gt;&lt;li&gt;A Poet: The many splendors of love...&lt;/li&gt;&lt;li&gt;A Computer Programmer: printf("%d\n",  1+1);&lt;/li&gt;&lt;li&gt;A Computer Scientist: 10&lt;/li&gt;&lt;li&gt;Bush: that is classified for national security reasons.&lt;/li&gt;&lt;li&gt;Obama: How about we fund that research out of the stimulus money?&lt;/li&gt;&lt;li&gt;A Drunk: Shoe.&lt;/li&gt;&lt;li&gt;A Policeman: I'll ask the questions here unless you want to get tasered.&lt;/li&gt;&lt;li&gt;A Ninja: (Could not find one to ask)&lt;/li&gt;&lt;li&gt;Chuck Norris: That would be my Punch (tm) followed by my hallmark Roundhouse Kick (tm).&lt;/li&gt;&lt;li&gt;A Manager: Lets hold a meting to plan the response to that question.&lt;/li&gt;&lt;li&gt;A Consultant: I see we are funded for three weeks work, so come back in three weeks for the answer.&lt;/li&gt;&lt;li&gt;A Tester: Your program crashed while calculating the answer.&lt;/li&gt;&lt;li&gt;Buddha: Your attachment to the number one causes suffering for all beings.&lt;/li&gt;&lt;li&gt;The Pope: The correct question is what is 1 + 1 + 1.&lt;/li&gt;&lt;li&gt;Global Warming Alarmists: Our simulation shows that the answer will be increasing over time.&lt;/li&gt;&lt;li&gt;Global Warming Deniers: Our leading scientist says the answer is 2 but has recently been fired for saying so.&lt;/li&gt;&lt;li&gt;Mormons: Actually 1 + 2 or 1 + 3 works well too.&lt;/li&gt;&lt;li&gt;McDonald's Employee: Do you want fries with that.&lt;/li&gt;&lt;li&gt;Picasso: N&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-6241377768934743716?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/6241377768934743716/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=6241377768934743716' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/6241377768934743716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/6241377768934743716'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2009/06/what-is-1-1.html' title='What is 1 + 1?'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-946372329609710259</id><published>2009-05-05T13:13:00.000-07:00</published><updated>2010-08-19T14:50:49.602-07:00</updated><title type='text'>Worlds Apart</title><content type='html'>I recently read the article &lt;a href="http://www.phys.ufl.edu/%7Edet/phy2060/heavyboots.html"&gt;Heavy Boots&lt;/a&gt;  and was struck by the difference of world view that some people can have.&lt;br /&gt;&lt;br /&gt;The article is about "If you were standing on the moon and drop a rock, will it float away, or fall down".  The answer is obvious to me. But then I got thinking...&lt;br /&gt;&lt;br /&gt;I grew up with a father that designed the lunar orbiters in the 1960's, build telescopes for fun, we launched rockets, read SciFi, I have a degree in engineering.  I can remember standing on a street on a hill in Spain in 1980, with a perfect starry sky, and several planets and moon in the sky, and the sun had just set.  I could perfectly visualize the actual and relative motions of all the bodies in my mind.&lt;br /&gt;&lt;br /&gt;So many people live in a different world than I do.  They have no real concept of science or how the world around them works.  It reminds me of the dark ages when the world was haunted by spirits and people were killed for witchcraft. (See Monty Python and the Holy Grail, "She's a witch!")  Such persecutions were not done so much out of cruelty , but on response to a world view of "how things work".&lt;br /&gt;&lt;br /&gt;There seems to be a common thread through conflict and conflicting world views.&lt;br /&gt;&lt;br /&gt;1.) If you have conflicting world views, and you try to change the world view of someone else, they can get very angry.  This seems to be because people see attacks on their world view as a personal attack on them self.  Everyone's world view has a huge chunk in it called "I" and who "I" is.  A change of world view is nearly impossible for anyone over 20, and difficult for anyone over 2.&lt;br /&gt;&lt;br /&gt;2.) When people see you as threatening their well-being according to their world view, they will violently defend them selves.&lt;br /&gt;&lt;br /&gt;Therefore...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Religious conversions &lt;/span&gt;are almost never a change in world view, they are a coming home to what is viewed as the world view they always had but never quite had right. &lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Wars &lt;/span&gt;are always justified as "If we don't act they will kill us."  This may seem obvious, but in any war both sides always are justified this way.  E.g. The Iraq war.  If the USA didn't do something, those #$%@# terrorists will come over here and kill us." and the terrorists justify their actions as, "Those foreigners are trying to foster democracy which will reduce our power and will result in our death". (Note: I won't dignify their actions as actually religiously motivated.  The leaders are thugs that justify their actions by assuming all the rest of the world is thugs, and there are a few rank-and-file terrorists that are actually  motivated by religious ideals. See Bully below.)&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Teenagers &lt;/span&gt;are solidifying their world view, but run hard up against reality, and so it is a difficult time of life.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Religion and Science: &lt;/span&gt;Many religions see science as an attack on their safety and salvation and that of their children. Scientists see religion as undermining the science that has brought us such a high standard of living, and endangering lives.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Swine Flu: &lt;/span&gt;The recent Swine Flue Hysteria, in several countries they want to or have killed all the pigs.  This exactly fits a world view that includes pigs being fundamentally unclean, the flu has to do with cleanliness, governments can not be trusted, and a past history that includes plagues, and western science that is simply one more way for the heathen invaders to lie.&lt;/li&gt;&lt;li&gt;In &lt;span style="font-weight: bold;"&gt;politics&lt;/span&gt;, government decisions can be a basic way of ensuring standard of living and opportunities for people.  There seem to be two basic world views on the USA, one is 'government is the problem' typified by the Republican view, and 'government is the solution' typified by the Democratic view.  Thus politics is a very serious game indeed. We could argue quite a bit about whether Republican and/or Democratic actions seem to match such stated world views.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;A &lt;span style="font-weight: bold;"&gt;bully &lt;/span&gt;or crook.  there is a world view that the world is difficult, everyone is a bully (some more successful than others) and the only way to survive as a person is to be the most skilled bully. "Survival of the Strongest".  The opposing view is along the lines of Brotherhood, or "I am a child of God, and so is everyone else", etc.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Pacifists:&lt;/span&gt; there is a world view that violence is unjustified no matter what.  This vew tends to follow along the lines that the world has a 'rightness' to it and if we would just calm down, the bullies will change their world view.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Elitists:&lt;/span&gt; The world view that I am smarter than most every one else and I know what is best for you, so toddle along there and let me run things.  This is one of the most dangerous world views there is.  It is the exact opposite of brotherhood. (Ok, I'll bite, this is Obama all the way.)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Such a list could go on and on.&lt;br /&gt;&lt;br /&gt;Now look at the specific conflicts of out time in light of this.  Think "what are the conflicting world views".  Who holds which views? (Not necessarily the neat packaged world views the opposition supposedly has.)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Us vs. Terrorism&lt;/li&gt;&lt;li&gt;Science and Religion&lt;/li&gt;&lt;li&gt;Bailouts vs. Let-em-die&lt;/li&gt;&lt;li&gt;Right to Choose vs. Right to Life&lt;/li&gt;&lt;li&gt;Global Warming vs. Many alternate priorities and conclusions.&lt;/li&gt;&lt;li&gt;Socialized "fill in the blank" vs. Free Market.&lt;/li&gt;&lt;li&gt;What Paris Hilton wears vs. Who is Paris Hilton?&lt;/li&gt;&lt;li&gt;Save the Planet vs. Save the Humans.&lt;/li&gt;&lt;li&gt;USA vs. China&lt;/li&gt;&lt;li&gt;Illegal Immigrants vs. Jobs&lt;/li&gt;&lt;li&gt;Inner Peace vs. Outer Appearance&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Paper vs. Plastic vs. Bring Your Own Bag  (Yes I'm serious about this one.  It is a shallow placeholder for much deeper beliefs.)&lt;/li&gt;&lt;li&gt;Gun Control vs. Right to Bear Arms.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;So what is the whole point here.  Ill preach a bit now using absolutes...&lt;br /&gt;&lt;br /&gt;If people would just realize that rule number one is "If it involves violence, be very cautious".&lt;br /&gt;If justifying your acts of violence includes &lt;span style="font-style: italic;"&gt;any &lt;/span&gt;level of indirect reasoning, it is almost certainly wrong.&lt;br /&gt;Violence is always a result of conflicting basic world view issues.  In all cases violence will never change someone's view. &lt;br /&gt;Seek to understand first.&lt;br /&gt;&lt;br /&gt;What would ever justify violence?&lt;br /&gt;A direct and obvious attack on person, your family, or your ability to be left alone to 'do your own thing'.&lt;br /&gt;&lt;br /&gt;All other cases should be handled with talking, and talking, and talking.&lt;br /&gt;&lt;br /&gt;And then there is something deeper.  Our values, world view, and beliefs are really conclusions that we have drawn from our individual experience.  Everyone is in this same trap of a single thread of experience.  'They' can't hold any other world view because it is a result of their experience. Once you truly understand this, you can be very tolerant of others.  Maybe this is the ultimate 'Brotherhood'.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;There but for the grace of God, go I.&lt;/blockquote&gt;&lt;br /&gt;Your Fellow Human Being&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-946372329609710259?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/946372329609710259/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=946372329609710259' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/946372329609710259'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/946372329609710259'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2009/05/worlds-apart.html' title='Worlds Apart'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-3067332615687887741</id><published>2009-04-22T09:09:00.000-07:00</published><updated>2009-04-22T09:21:26.867-07:00</updated><title type='text'>Air Energy vs. Ocean Energy</title><content type='html'>With all this talk about climate change and such, I got curious about how much total energy is stored in the heat in the atmosphere vs. the oceans.  It seems that we talk about climate change, but because we are humans, we are highly biased toward the air being the climate and somewhat ignore the oceans.  If we were all dolphins, we would see the oceans and ignore the air.&lt;br /&gt;&lt;br /&gt;SO lets get some numbers, all gleaned from Google searches, mostly with hits on Wikipedia...&lt;br /&gt;&lt;br /&gt;Weight of the atmosphere: 5.1x10^18 kg.&lt;br /&gt;Weight of the oceans:          1.5x10^21 kg.&lt;br /&gt;&lt;br /&gt;So the water out weighs the atmosphere by&lt;span style="font-weight: bold;"&gt; 294 times&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;But, water holds more heat per kg than air...&lt;br /&gt;&lt;br /&gt;The specific heat of water: 2.015 kJ/kg-K.&lt;br /&gt;&lt;br /&gt;This means that it takes 2015 Joules of energy to raise one killogram of water by one degree Kelvin or Centigrade.&lt;br /&gt;&lt;br /&gt;the specific heat of air: 1.0 kJ/kg-K&lt;br /&gt;&lt;br /&gt;So water holds about twice the heat per pound than air, so&lt;br /&gt;&lt;br /&gt;The total heat needed to change the temperature of the ocean vs. the air is &lt;span style="font-size:130%;"&gt;&lt;br /&gt;      &lt;span style="font-size:180%;"&gt; 588 times greater&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:180%;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;My point?&lt;br /&gt;&lt;br /&gt;the global temperature that we all measure and quote as 'global warming' is irrelevant.&lt;br /&gt;&lt;br /&gt;The oceans are the real climate and fluctuations in the atmosphere are trivial.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-3067332615687887741?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/3067332615687887741/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=3067332615687887741' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/3067332615687887741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/3067332615687887741'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2009/04/air-energy-vs-ocean-energy.html' title='Air Energy vs. Ocean Energy'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-1894676491097190101</id><published>2009-04-11T12:01:00.000-07:00</published><updated>2009-04-11T12:17:16.760-07:00</updated><title type='text'>XNA, XACT, and Sound</title><content type='html'>Our project had a lot of difficulty in getting sound to work in XNA and in communication between the programmers and the sound artists.&lt;br /&gt;This tutorial is intended as instructions for the audio folks at Sandswept Studios, but feel free to use it too.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Key Concepts&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;XACT lets the audio engineers tweak all sorts of sound parameters without the programmers having to worry about it.&lt;br /&gt;The programmer just plays the cue.&lt;br /&gt;The audio engineer can tweak volume, sound fall off distance, etc.&lt;br /&gt;&lt;br /&gt;First and most important, you must have the correct version of XACT to work with XNA!&lt;br /&gt;This means that you must use the XACT that comes with XNA Studio.&lt;br /&gt;On my machine XACT is at C:\Program Files\Microsoft XNA\XNA Game Studio\v3.0\Tools\Xact.exe&lt;br /&gt;&lt;br /&gt;When you are editing sounds in XACT it is nice to be able to hear them, so you have to run AudConsole.exe&lt;br /&gt;that is in the same directory that Xact.exe is in. &lt;br /&gt;You would think that XACT could just play sounds, but no, you have to run AudConsole.exe&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Create An XACT Project&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So lets get started.   Run XACT and create a new project.&lt;br /&gt;File ==&gt; New project&lt;br /&gt;I put the new project at C:\Users\rkeene\Documents\AudioTest\ and called it AudioTest&lt;br /&gt;&lt;br /&gt;XACT Uses wave banks which are the 'raw sound'  usualy from a .wav or .aif file.&lt;br /&gt;We will use the regular old windows chimes sound. So create a wave bank&lt;br /&gt;Wave Banks ==&gt; New Wave Bank&lt;br /&gt;You should get an empty wave bank window.&lt;br /&gt;Now go find the .wav file we want.  On my Vista machine it is in&lt;br /&gt;C:\WINDOWS\Media\chimes.wav&lt;br /&gt;So drag-n-drop that file onto the WaveBank area.&lt;br /&gt;&lt;br /&gt;Now we want a sound bank, which ties a raw wave bank entry to all sorts of settings like volume and pitch.&lt;br /&gt;Sound Banks ==&gt; New Sound Bank&lt;br /&gt;Then drag and drop the chimes.wav wave bank entry to the upper part of the Sound Banks window.&lt;br /&gt;Sounds let you add event like volume changes, pitch changes, etc.  creating nifty effects.&lt;br /&gt;&lt;br /&gt;We also need an actual cue. &lt;br /&gt;This is the name the programmer will use to find the cue and play it in the C# code in XNA.&lt;br /&gt;So, drag-n-drop the sound to the lower part of the cues area.&lt;br /&gt;&lt;br /&gt;Now we have a wave bank, a sound bank, and a project.  So click on the save icon to save the project.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Sound Fade With Distance&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In most games it is nifty to have sounds fade as your view point gets furthur away from the sound source.&lt;br /&gt;Like in DETOUR the factory makes machine noises and we want them to fade out as the player's viewpoitn gets furthur from the factory.&lt;br /&gt;But there are 'big' sound like nukes going off, and 'small' sounds like a dog barking.  Big sounds fade out less with distance, and small sounds fade quickly.&lt;br /&gt;In XACT there are RPC Presets that let you setup this fade out.&lt;br /&gt;&lt;br /&gt;You need to determine what units distance is in in your game.  Is it meters? Inches? Pixels?&lt;br /&gt;On the DETOUR board tiles are 254x254 game units.  These are also called World Coordinates.&lt;br /&gt;So while the view point may be on tile 12,5 the world coordinates will be 12*254, 200, 5*254&lt;br /&gt;which is X,Y,Z coordinates.  The board is in the XZ plane and Y is 'up'.&lt;br /&gt;Thus for our factory sound we want to be at full volume if you are looking at the factory and fade out&lt;br /&gt;to silent in about 2000 units of distance.&lt;br /&gt;&lt;br /&gt;First lets look at Variables.  On the left side there is Variables ==&gt; Cue Instance ==&gt; Distance&lt;br /&gt;This is the variable that we will relate to volume. Since our largest board is about 40x40 and thus&lt;br /&gt;10,000 world units max, we want to limit distance ranges to 0 to 10000.&lt;br /&gt;So click on Distance and down below set the range to 0 and 10000.&lt;br /&gt;&lt;br /&gt;Next drag and drop your cue on to the RPC Presets item on the left of the screen. &lt;br /&gt;This attaches the cue to the Presets.&lt;br /&gt;Click on RPC Presets and a window comes up with a black window and lines on it. &lt;br /&gt;The lines are (or will be) the sound level related to distance.&lt;br /&gt;&lt;br /&gt;So in the RPC Presets window you first select the Variable whic is Distance.&lt;br /&gt;Then select the Object whic is Sound, and then the Parameter which is Volume.&lt;br /&gt;Thus "The distance effects sounds by changing colume."&lt;br /&gt;&lt;br /&gt;Now you can drage the line around and get whatever sound vs. distance function you like.&lt;br /&gt;You can double click on the line to make a new drag point.  And Ctrl-Z undoes mistakes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Testing 1 2 3 Testing&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Make sure AudConsole is running, and up at the center top of the Xact tools there is a play button.&lt;br /&gt;Click on the Cue, and then click play.  Do you hear it?&lt;br /&gt;Also, in the RPC Presets tool you can set the distance, click on the line, and then click the play button&lt;br /&gt;in the RPC window and hear the sounds volume at a given distance.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Exporting&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Next we need to export from XACT for XNA.&lt;br /&gt;At the top of the XACT windows is a View menu and the first two items are View XBox36 and View Windows.&lt;br /&gt;This is how you switch between compiling and exporting for the XBox and the PC.&lt;br /&gt;&lt;br /&gt;You want to be able to tell the XBox vs. Windows files appart so click on the Wave Bank in the left tree,&lt;br /&gt;and on the lower left there should be fields for&lt;br /&gt;XBox 360 Build Path and Windows Build Path.&lt;br /&gt;&lt;br /&gt;We use the convention that the file names end with _w or _x.  So change these to be differnet.&lt;br /&gt;Do the same for the sound banks.&lt;br /&gt;Do the same for the top most level project too.&lt;br /&gt;&lt;br /&gt;In my test project the top level is AudioTest&lt;br /&gt;so the build path is AudioTest_w.xgs and SudioTest_x.xgs&lt;br /&gt;The sound banks are SB1_w.xsb and SB1_x.xsb&lt;br /&gt;and wave banks are WB1_w.xwb and WB1_x.xwb&lt;br /&gt;&lt;br /&gt;Now you build, so make sure View is on View Windows Properties, and click the Builds The Current Project&lt;br /&gt;icon in the top center of the XACT windows.&lt;br /&gt;It will ask about the report you might want.  I check Concise and enter rpt_w.txt&lt;br /&gt;&lt;br /&gt;The reason for the report is that as your game gets bigger and has zillions of cues, the report helps you keep thing straight.&lt;br /&gt;You can also give the report to the programmer so they know what the cue names are.&lt;br /&gt;This is where all those 'notes' fields come in handy.&lt;br /&gt;It is wise to add a note entry to every cue describing what it is intended for in the game.&lt;br /&gt;&lt;br /&gt;Phew!  We have exported the windows version.&lt;br /&gt;&lt;br /&gt;You can set the View to View XBox Properties and export again to get the XBox version of the files.&lt;br /&gt;Windows version files will not work on the XBox.  Period.&lt;br /&gt;&lt;br /&gt;Note: sound effects (sfx) are usually loaded into memory in advance so there is no delay to play them.&lt;br /&gt;Music is HUGE so it is streamed from disk to the audio hardware on-the-fly with buffers.&lt;br /&gt;If you click on the Wave Bank, the properties below will include Streaming or InMemory.&lt;br /&gt;Sound effect should be InMemory, and Music should be Streaming.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;C# and XNA and Sounds&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ok, now you have all the sounds build for XNA.&lt;br /&gt;&lt;br /&gt;Now we move to the XNA C# world.&lt;br /&gt;In XNA you have to load the project (.xgs) the sound bank (.xsb) and the wave bank (.xwb)&lt;br /&gt;Then you find the cue, give it 3D position (optional), and play it. &lt;br /&gt;If your sound person did things correctly, then that is all.&lt;br /&gt;&lt;br /&gt;First we need to get the files into the XNA project. &lt;br /&gt;So copy the three files into the Content area.  (Ok, get organized and use a subdirectory, etc.)&lt;br /&gt;Now in the Content part of the Solution Explorer, Add ==&gt; Existing Item&lt;br /&gt;You will need to set the pop up file chooser to All Files (*.*).  It initially filters for non-sound files.&lt;br /&gt;Select the three files and hit Ok.&lt;br /&gt;&lt;br /&gt;They are now in the project, but you need to tell XNA and Visual Studio how to use them.&lt;br /&gt;Select all three under the Content area and in the properties area set...&lt;br /&gt;&lt;blockquote&gt;Build Action: Content&lt;br /&gt;Content Importer: XACT Project - XNA FrameWork&lt;br /&gt;Content ProcessorXACT Project - XNA FrameWork&lt;br /&gt;Copy To Output Directory: Copy if Newer&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Ok, now build the project to see if everything is Ok.&lt;br /&gt;&lt;br /&gt;Now we need to load the sounds into our game so&lt;br /&gt;add three new class instance level variables to your Game.cs file&lt;br /&gt;&lt;br /&gt;        public AudioEngine TheAudioEngineTest;&lt;br /&gt;        public WaveBank TheWaveBankTest;&lt;br /&gt;        public SoundBank TheSoundBankTest;&lt;br /&gt;&lt;br /&gt;And in the LoadContent method put something like...&lt;br /&gt;&lt;br /&gt;            TheAudioEngineTest = new AudioEngine("Content\\AudioTest_w.xgs");&lt;br /&gt;            TheWaveBankTest = new WaveBank(TheAudioEngineTest, "Content\\WB1_w.xwb");&lt;br /&gt;            TheSoundBankTest = new SoundBank(TheAudioEngineTest, "Content\\SB1_w.xsb");&lt;br /&gt;            TheAudioEngineTest.Update();&lt;br /&gt;&lt;br /&gt;The Update there is to 'fail fast' if there is a problem, and is not required.&lt;br /&gt;&lt;br /&gt;Note: If you play a cue and never call Update on the audio engine, you not hear anything.&lt;br /&gt;Note: The above is for in-memory sounds like sound effects.  Music is streamed and the code might&lt;br /&gt;then look like...&lt;br /&gt;&lt;br /&gt;            TheAudioEngine = new AudioEngine("Content\\music_w.xgs");&lt;br /&gt;            TheWaveBank = new WaveBank(TheAudioEngine, "Content\\music_w_wb.xwb", 0, 4);&lt;br /&gt;            TheSoundBank = new SoundBank(TheAudioEngine, "Content\\music_w_sb.xsb");&lt;br /&gt;            TheAudioEngine.Update();&lt;br /&gt;Note the 0,4 on the end of the WaveBank entry.  This is critical.It is the offset and packet size&lt;br /&gt;and effects how smoothly the music plays back.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Oops&lt;/span&gt; - We need to differentiate between XBOX and not XBOX code so we need a&lt;br /&gt;#if XBOX&lt;br /&gt; // Load the XBox versions of the files.&lt;br /&gt;#else&lt;br /&gt; // Load the Windows versions of the files.&lt;br /&gt;#endif&lt;br /&gt;around our loads where the _w becomes _x&lt;br /&gt;&lt;br /&gt;Now lets play our sound.&lt;br /&gt;The simplest way is...&lt;br /&gt;&lt;br /&gt;TheSoundBank.PlayCue("mycue");&lt;br /&gt;&lt;br /&gt;Also in the main Update in your game you need to Update TheSoundEngine&lt;br /&gt;&lt;br /&gt;You can also do...&lt;br /&gt;&lt;br /&gt;Cue c = TheSoundBank.GetCue("mycue");&lt;br /&gt;c.Play();&lt;br /&gt;&lt;br /&gt;But of course, we want possitional sound so we do...&lt;br /&gt;                Object o = Gm.TheAudioEngineTest.RendererDetails;&lt;br /&gt;                AudioListener aListen = new AudioListener();&lt;br /&gt;                aListen.Position = FocusTile.LocationWorld;&lt;br /&gt;                AudioEmitter aEmit = new AudioEmitter();&lt;br /&gt;                aEmit.Position = FactoryTile.LocationWorld;&lt;br /&gt;                Cue c = Gm.TheSoundBankTest.GetCue("TestCue1");&lt;br /&gt;                float d = (aEmit.Position - aListen.Position).Length();&lt;br /&gt;                c.SetVariable("Distance", d);&lt;br /&gt;                c.Apply3D(aListen, aEmit);&lt;br /&gt;                c.Play();&lt;br /&gt;&lt;br /&gt;Ok, the FocusTile.LocationWorld gives me the X,Y,Z coordinates of the tile in world units.&lt;br /&gt;The FactoryTile is where my factory is.&lt;br /&gt;The d is the distance between the two.&lt;br /&gt;We have to set the Distance variable on the cue, and the Apply3D does the stereo&lt;br /&gt;left-right speaker shift.&lt;br /&gt;(You left and right speakers are in the correct place on your desk top?&lt;br /&gt; The one with the volume knob is always the right speaker.)&lt;br /&gt;&lt;br /&gt;Wow, that is how sound is done.&lt;br /&gt;&lt;br /&gt;XBox Note: When you make the XNA project for the XBox you must remove the wave bank, project, and sound bank files in Content&lt;br /&gt;and re-add the XBox versions.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Tips and Tricks&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Randomize Cue Sound Choice&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;You can make a single cue play several different sound randomly.  The programmer does not need to even know which one will play.&lt;br /&gt;Cues have a weight or probability.  You can give each sound in the cue a different weight and that is how often they will get picked.&lt;br /&gt;This is cool if you have a repetitive sound, like gun fire, and you want to randomly choose between several different gun sounds to make it not-so-boring.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;C# Code Structure&lt;/span&gt;&lt;br /&gt;You can have several Audio Engines at the same time.  We break out one music engine, and 3 different Sfx engines.  Then we have a PlaySfx call that takes an enum flag as to which Sfx set the cue is in.  This makes our code control checkins much faster since we don't have one giant Sfx Sound Bank and Wave Bank.&lt;br /&gt;&lt;br /&gt;It is also handy to have a currently playing music track, and a NextMusicCue that will get played when the current one finishes.&lt;br /&gt;&lt;br /&gt;We also have an SfxItem class that hold info about a currently playing item and each of the Sfx engines.  So our overall update method loos like this...&lt;br /&gt;&lt;br /&gt;        private void UpdateAudioEngines()&lt;br /&gt;        {&lt;br /&gt;            if (TheAudioEngineTest != null)&lt;br /&gt;            {&lt;br /&gt;                TheAudioEngineTest.Update();&lt;br /&gt;            }&lt;br /&gt;            if (TheAudioEngine != null)&lt;br /&gt;            {&lt;br /&gt;                TheAudioEngine.Update();&lt;br /&gt;                if (CurrentMusicCue != null &amp;amp;&amp;amp; CurrentMusicCue.IsStopped &amp;amp;&amp;amp; NextMusicCue != null)&lt;br /&gt;                {&lt;br /&gt;                    CurrentMusicCue = NextMusicCue;&lt;br /&gt;                    NextMusicCue = null;&lt;br /&gt;                    CurrentMusicCue.Play();&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            if (SfxActions != null &amp;amp;&amp;amp; SfxActions.TheAudioEngine != null)&lt;br /&gt;            {&lt;br /&gt;                SfxActions.TheAudioEngine.Update();&lt;br /&gt;            }&lt;br /&gt;            SfxItem.UpdateAll();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;Enjoy&lt;br /&gt;&lt;br /&gt;T.F.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-1894676491097190101?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/1894676491097190101/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=1894676491097190101' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1894676491097190101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1894676491097190101'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2009/04/xna-xact-and-sound.html' title='XNA, XACT, and Sound'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-238332326722440554</id><published>2009-03-03T09:44:00.000-08:00</published><updated>2009-03-04T10:37:42.292-08:00</updated><title type='text'>How to Dig for Truth</title><content type='html'>I read a recent post &lt;a href="http://thelastpsychiatrist.com/2008/10/the_dumbest_generation_is_only.html"&gt;here &lt;/a&gt;there is some talk about the lack of information on the internet.&lt;br /&gt;&lt;br /&gt;There in fact is no lack of very deep scientific information.  The major problem is finding it.&lt;br /&gt;General news articles are mostly wrong and usually the articles do not even match the conclusions of the underlying scientific papers.&lt;br /&gt;&lt;br /&gt;There are two issues.  First, finding real scientific papers, and second, understanding them.&lt;br /&gt;&lt;br /&gt;So I'll guide you through an example...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;The Initial News Article&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Tuesday March 3, 2009 there is an article stating...&lt;br /&gt;&lt;a href="http://uk.reuters.com/article/healthNewsMolt/idUKTRE5224DN20090303"&gt;This &lt;/a&gt;article in on Google's front page news, and the title is&lt;br /&gt;&lt;h1 style="font-weight: normal;"&gt;&lt;span style="font-size:100%;"&gt;&lt;a href="http://uk.reuters.com/article/healthNewsMolt/idUKTRE5224DN20090303"&gt;Older people face greater HIV infection risks: study&lt;/a&gt;&lt;/span&gt;&lt;/h1&gt;and it is on the Reuters UK page.&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;* Doctors failing to screen for HIV in older patients&lt;span id="midArticle_byline"&gt;&lt;/span&gt;&lt;/p&gt;&lt;span id="midArticle_0"&gt;&lt;/span&gt;       &lt;p&gt;* HIV progresses faster to AIDS in those aged 50-plus&lt;/p&gt;&lt;span id="midArticle_1"&gt;&lt;/span&gt;       &lt;p&gt;* Older people more likely to risk unprotected sex&lt;/p&gt;&lt;span id="midArticle_2"&gt;&lt;/span&gt;       &lt;p&gt;By Laura MacInnis GENEVA (Reuters) - Doctors are failing to diagnose HIV in older patients, who are exposed to greater risk of infection as erectile dysfunction drugs extend their sex lives, a study published by the World Health Organization said on Tuesday.&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;One Level Down, The source news article.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ok, lets go find the original study...&lt;br /&gt;Lucky, this one gives us a clue, it is &lt;a href="http://www.who.int/en/"&gt;WHO&lt;/a&gt;, the World Health Organization.  So we google the site.&lt;br /&gt;It's the top hit on Google.&lt;br /&gt;An it is the top blurb on the WHO web site.&lt;br /&gt;&lt;blockquote&gt;3 March 2009 -- HIV prevalence and incidence in people 50 years of age and over seem surprisingly high and the risk factors are largely unexplored. Understanding the epidemiology of HIV infection in older individuals can lead to interventions to make these years safer and more enjoyable, according to articles in the March edition of the WHO Bulletin.&lt;br /&gt;&lt;/blockquote&gt;Ah, there is a link to the&lt;a href="http://www.who.int/bulletin/volumes/87/3/09-064030/en/index.html"&gt; actual bulletin&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;The 'Real' Story and What was the Source of Funding&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;This has many authors, so now our trust level can go up some.  These look like actual scientists.&lt;br /&gt;See those little reference letters next to their names?  those tell where they are from .&lt;br /&gt;&lt;blockquote&gt;a. Department of HIV/AIDS, World Health Organization, 20 avenue Appia, 1211 Geneva 27, Switzerland.&lt;br /&gt;b. Independent Consultant, Geneva, Switzerland.&lt;br /&gt;c. St Olaf College, Northfield, MN, United States of America.&lt;/blockquote&gt;Now a. is the HIV/AIDS department.  You can guess that they will have an agenda.  Given that it is WHO, they will have scientific training, and are funded by, hmmm.  lets see who pays their bills...&lt;br /&gt;A google of &lt;span style="font-weight: bold;"&gt;WHO funding&lt;/span&gt; gets about the third hit down as Wikipedia, and the very first line says ...&lt;br /&gt;&lt;blockquote&gt;The &lt;b&gt;World Health Organization&lt;/b&gt; (&lt;b&gt;WHO&lt;/b&gt;) is a specialized agency of the &lt;a href="http://en.wikipedia.org/wiki/United_Nations" title="United Nations"&gt;United Nations&lt;/a&gt; (UN) that acts as a coordinating authority on international &lt;a href="http://en.wikipedia.org/wiki/Public_health" title="Public health"&gt;public health&lt;/a&gt;.&lt;/blockquote&gt;Ok, so they are part of the UN, which is a ultra political organization.  Just keep that in mind.&lt;br /&gt;&lt;br /&gt;b. above is an independent consultant.&lt;br /&gt;That could mean just about anything.  So, who is Brian G Williams, back to google.&lt;br /&gt;Wow, lots of hits.  Lets try Brian G. Williams Geneva.  The sixth hit down is &lt;a href="http://www.sciencemag.org/cgi/reprint/sci;301/5639/1535.pdf"&gt;Science magazine with a list&lt;/a&gt; of some papers he has co-authored.  This guy is definitely for real in the HIV research community.  And he has worked a lot with the UN.&lt;br /&gt;&lt;br /&gt;Then there are several references with c.&lt;br /&gt;I could search the first one, Chris Miller but that name is so common, I'll search a more unique name, Emily Segar and add in Olaf to get the university hits....&lt;br /&gt;Hmm, she shows up as a student graduating this year, and very big on the golf team.&lt;br /&gt;so I add HIV as a search word, and now I see college news about the research.&lt;br /&gt;In here is &lt;a href="https://ncur.uwlax.edu/ncur2009/search/Display_NCUR.aspx?id=20435"&gt;the 23rd National Conference on Undergraduate Research&lt;/a&gt; where the same authors are showing off their study.&lt;br /&gt;&lt;br /&gt;This is the abstract...&lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;&lt;span id="ctl00_ContentPlaceHolder1_abstract"&gt;Over 22 million individuals in sub-Saharan Africa are infected with Human Immunodeficiency Virus (HIV). Recent epidemiological research suggests that an unexpectedly high prevalence of HIV exists among the elderly in South Africa, particularly among females (Schmid et al., 2004). This trend deviates from the norm in most countries, where the prevalence of HIV infection steadily decreases after the age of 25. In the current study, we sought to (1) describe the age specific prevalence of HIV for men and women in Sub-Saharan Africa, (2) identify the risk factors associated with HIV prevalence in elderly populations and (3) compare and contrast risk factors between sub-Saharan African countries. We utilized individual-level data from 16 sub-Saharan African countries in the Demographic Health Surveys (DHS). The DHS surveys were conducted between 2002 and 2006 using a cross-sectional stratified clustered sampling methodology, which, in theory, allows findings to be generalized to each country’s population. The surveys collected data on household and respondent characteristics, socioeconomic status, education, knowledge and beliefs about sexually transmitted disease, health status, nutrition, and HIV status. Due to the nature of the sampling method, we incorporated weighted estimates for each individual (N=100,000+) into the prevalence estimates. Multiple logistic regression analyses were performed to identify potential socioeconomic, demographic, and cultural factors that were associated with HIV prevalence in elderly populations. We hope to identify whether an increased prevalence of HIV in the elderly exists in sub-Saharan African countries, and which factors may mitigate the risk for this population. Implications for future research of the epidemiology of HIV in sub-Saharan Africa are discussed.&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;Oh, it is a study they did in Africa.&lt;br /&gt;I wonder who the professor at the university doing the study is.  Maybe the first name in the list? David Tonyan Olaf gets a hit on the same article.&lt;br /&gt;Ok, so I go to the top level web site for St. Olaf college, then faculty, then departments.&lt;br /&gt;First I went back and read the names of the c. people.&lt;br /&gt;Ok, I got sick of digging out the names.  I suppose I could email one of the students and ask who the acedemic advisor is.  But...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;A Nugget of Facts Not in the News Articles&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;Did you notice the line in the abstract above...&lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;&lt;span id="ctl00_ContentPlaceHolder1_abstract"&gt;This trend deviates from the norm in most countries, where the prevalence of HIV infection steadily decreases after the age of 25. &lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;What the heck. When I read the news article I was thinking along the lines of good old USA retirement homes.  Why they must be hives of lust! skyrocketing HIV rates for the elderly!&lt;br /&gt;What about dear old Mom!&lt;br /&gt;&lt;br /&gt;Nope.  Not even the core idea.  The core idea of the paper is that African HIV rates are high for the elderly, in contrast to the rest of the world.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;What we Didn't Do&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;We got off lucky on this one and did not have to read the actual scientific paper. Aand no, I did not plan it ahead of time.  I wrote this blog as a stream of thought, as I did the research.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;The Point&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;The whole point of this article is that YOU can do the research on any topic.  Follow the rabiit down the hole.  You never know where it will lead.&lt;br /&gt;&lt;br /&gt;TF&lt;br /&gt;&lt;br /&gt;P.S. I am NOT going to go back and edit or correct this article like I usualy do.  It is a stram of thought, as it is.  Typos and everything.  :-)&lt;br /&gt;&lt;br /&gt;P.P.S. I have to give credit to the WHO thought.  They point out that in the developed countries HIV in the elderly is slowly going up.  So it is not entirely a wrong news story.&lt;br /&gt;But this begs the question; Is the WHO just trying to get more AIDS funding, and is it the best use of the money for world health issues?  Yes, again, the UN is highly political.&lt;br /&gt;&lt;br /&gt;P.P.P.S. Not that the WHO article title has the word Unexplored in it.  In other words they have not yet explored the issue of the aging and HIV.  So the news article is still way off.&lt;br /&gt;&lt;br /&gt;P.P.P.P.S. After digging for the truth, wait a day or two and then rethink and reread the information.  And dig a little more.  On a technical subject it helps to read at least 6 technical papers (not news articles) on the subject to get more balance.  And if the subject is climate, try reading some older papers from BAIT (Before An Inconvenient Truth).&lt;br /&gt;&lt;br /&gt;P.P.P.P.P.S. the next day, a &lt;a href="http://thelastpsychiatrist.com/2009/03/impulsivity_in_kindergarten_do.html"&gt;very good article on the same topic&lt;/a&gt;.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-238332326722440554?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/238332326722440554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=238332326722440554' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/238332326722440554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/238332326722440554'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2009/03/how-to-dig-for-truth.html' title='How to Dig for Truth'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-4576522697314721449</id><published>2008-09-25T20:14:00.000-07:00</published><updated>2008-10-01T14:40:17.291-07:00</updated><title type='text'>FBX and XNA - Part 6 - 40 Million Triangles Per Second</title><content type='html'>Now that we have pretty 3D models on the screen, the first impression is "Golly thats slow".&lt;div&gt;One test model I have is about 18000 polygons or 35000 triangles.  It displays at about 21 frames per second (FPS) on my PC.  In a game that would mean that 2 models on the screen would be but-ugly slow.  So lets move lots of the processing onto the Graphics Processing Unit (GPU).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The GPU uses a language call HLSL (High Level Shader Language).  What you do is write a somthing.fx file, add it to your project and then load the Effect with the Content loader.  Sounds easy.  The trick is what to put in the .fx file and how to drive it.  Fortunately Microsoft has already provided a SkinnedModelProcessor and it has a file called SkinnedModel.fx  We just is that as-is.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;HLSL defines method names in a .fx file for doing two things.  First is converting a model X,Y,Z point to world space so it can be used as one of the points in a triangle or line drawing.  Second is to determine the color of a point on a triangle as it is filled in on the screen (A Shader).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;SkinnedModel.fx has a section like this...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;pre&gt;// Vertex shader input structure.&lt;br /&gt;struct VS_INPUT&lt;br /&gt;{&lt;br /&gt;float4 Position : POSITION0;&lt;br /&gt;float3 Normal : NORMAL0;&lt;br /&gt;float2 TexCoord : TEXCOORD0;&lt;br /&gt;float4 BoneIndices : BLENDINDICES0;&lt;br /&gt;float4 BoneWeights : BLENDWEIGHT0;&lt;br /&gt;};&lt;/pre&gt;It indicates that each triangle corner is supposed to have a Position, a normal to the surface, a texture coordinate.  That is just like our previous code.  The BoneIndices is the index of the Deformer (Bone) that influences the point location with a weight of BoneWeights.  The trick here is that a float4 has a X,Y,Z,W values meaning that there can be up to 4 deformers and their associated matrices that can influence the point.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Note: The Position has a vector4 which means it has a X,Y,Z and the mysterious W.  Just set all the W's to 1.0f and it will work fine.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So we modify our code to generate this new structure in place of the previous DrawData point list.  We use the structure...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;pre&gt;    [Serializable]&lt;br /&gt;public struct SkinnedModelRec&lt;br /&gt;{&lt;br /&gt;public Vector4 Position;&lt;br /&gt;public Vector3 Normal;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// The UV texture coord.&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;public Vector2 TexCoord;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// We can have up to 4 bones influencing one vertex point and normal.&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;public Vector4 BoneIndices;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// We can have up to 4 bones per vertex.  These are the weights.  Leave them 0 of no bone.&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;public Vector4 BoneWeights;&lt;br /&gt;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Description of the elements of this structure.&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;public static readonly VertexElement[] VertexElements =&lt;br /&gt;new VertexElement[] {&lt;br /&gt; new VertexElement(0,0,VertexElementFormat.Vector4, VertexElementMethod.Default, VertexElementUsage.Position, 0),&lt;br /&gt; new VertexElement(0, sizeof(float) * 4, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Normal, 0),&lt;br /&gt; new VertexElement(0, sizeof(float) * 7, VertexElementFormat.Vector2, VertexElementMethod.Default, VertexElementUsage.TextureCoordinate, 0),&lt;br /&gt; new VertexElement(0, sizeof(float) * 9, VertexElementFormat.Vector4, VertexElementMethod.Default, VertexElementUsage.BlendIndices, 0),&lt;br /&gt; new VertexElement(0, sizeof(float) * 13, VertexElementFormat.Vector4, VertexElementMethod.Default, VertexElementUsage.BlendWeight, 0)&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;... some methods ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Notice the vertex element definition.  It tells XNA where the elements in the structure go in relation to the defeinitions in SkinnedModel.fx&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next we load all the points in the model, and the draw indices into the GPU&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;pre&gt;            TheVertexBuffer = new VertexBuffer(gd, typeof(SkinnedModelRec), DrawData.Length, BufferUsage.WriteOnly);&lt;br /&gt;TheVertexDeclaration = new VertexDeclaration(gd, SkinnedModelRec.VertexElements);&lt;br /&gt;TheIndexBuffer = new IndexBuffer(gd, typeof(int), DrawIndices.Length, BufferUsage.WriteOnly);&lt;br /&gt;TheVertexBuffer.SetData&lt;skinnedmodelrec&gt;(DrawData);&lt;br /&gt;TheIndexBuffer.SetData&lt;int&gt;(DrawIndices);&lt;br /&gt;&lt;/int&gt;&lt;/skinnedmodelrec&gt;&lt;/pre&gt;And then we can draw them.  I realize that all the code is not here.  This is just to get the idea of the style.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; private void DrawSingleMesh(GraphicsDevice gd, PTake CurrentTake, Effect effect, PMesh mesh, PModelTracker tracker)&lt;br /&gt; {&lt;br /&gt;     //mesh.CalcCurrentState(CurrentTake, tracker);&lt;br /&gt;     mesh.CalcAllDeformerMatrices(CurrentTake, tracker);&lt;br /&gt;&lt;br /&gt;     mesh.SetupGPU(gd);&lt;br /&gt;&lt;br /&gt;     gd.RenderState.CullMode = CullMode.None;&lt;br /&gt;     gd.VertexDeclaration = mesh.TheVertexDeclaration;&lt;br /&gt;     gd.Vertices[0].SetSource(mesh.TheVertexBuffer, 0, SkinnedModelRec.SizeInBytes);&lt;br /&gt;     gd.Indices = mesh.TheIndexBuffer;&lt;br /&gt;&lt;br /&gt;     // We draw all the triangles in a single texture at once.  Then switch to next texture.&lt;br /&gt;     // Sometimes textures repeat later in the list.&lt;br /&gt;     foreach (PTextureRun tr in mesh.DrawDataTextureSegments)&lt;br /&gt;     {&lt;br /&gt;         if (tr.TextureId (lessthan messes up HTML) 0)&lt;br /&gt;         {&lt;br /&gt;             // Some polygons have no texture and are just white with illumination.&lt;br /&gt;             // We should probably not allow untextured polygons.&lt;br /&gt;             //effect.TextureEnabled = false;&lt;br /&gt;             effect.Parameters["Texture"].SetValue(DefaultTexture);&lt;br /&gt;         }&lt;br /&gt;         else&lt;br /&gt;         {&lt;br /&gt;             //effect.TextureEnabled = true;&lt;br /&gt;             effect.Parameters["Texture"].SetValue(Textures[tr.TextureId].Tex);&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;         // Max bones in the SkinnedModel.fx is 59&lt;br /&gt;         Matrix[] bonesMatricies = new Matrix[59];&lt;br /&gt;         for (int i = 0; i lessthan mesh.DrawDeformers.Length; i++)&lt;br /&gt;         {&lt;br /&gt;             bonesMatricies[i] = mesh.DrawDeformers[i].Transform;&lt;br /&gt;         }&lt;br /&gt;         effect.Parameters["Bones"].SetValue(bonesMatricies);&lt;br /&gt;&lt;br /&gt;         effect.Begin();&lt;br /&gt;         foreach (EffectPass pass in effect.CurrentTechnique.Passes)&lt;br /&gt;         {&lt;br /&gt;             pass.Begin();&lt;br /&gt;&lt;br /&gt;             gd.DrawIndexedPrimitives(PrimitiveType.TriangleList,&lt;br /&gt;                 0,&lt;br /&gt;                 tr.MinVertexIdx,&lt;br /&gt;                 tr.MaxVertexIdx,&lt;br /&gt;                 tr.StartIdx,&lt;br /&gt;                 tr.PrimCount);&lt;br /&gt;&lt;br /&gt;             pass.End();&lt;br /&gt;         }&lt;br /&gt;         effect.End();&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;Easy as that. Then I tested it with a loop.  We can now put up lots of our model on the screen and hold 60 FPS.  The result is 40 million triangles per second.  Now that's where we need to be to play a game.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;TF&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-4576522697314721449?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/4576522697314721449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=4576522697314721449' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/4576522697314721449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/4576522697314721449'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2008/09/fbx-and-xna-part-6-40-million-triangles.html' title='FBX and XNA - Part 6 - 40 Million Triangles Per Second'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-7947838891500737874</id><published>2008-09-18T10:16:00.007-07:00</published><updated>2008-10-01T14:39:33.431-07:00</updated><title type='text'>FBX and XNA Part 5 - Animation Interpolation</title><content type='html'>One thing I glossed over was how you arrive at the 'current animation rotation' or translation.&lt;br /&gt;&lt;br /&gt;The Key: entries represent instants in time that the LimbNode is at a particular translation and rotation. (And scale and color and transparency, but we ignore theses.)  What we do is have a ModelTracker class that keeps track of the current values for the animation for every LimbNode.&lt;br /&gt;We simply interpolate between the instants in time.  But remember, the first entry is the beginning of the time line, and the last entry is the end so it is a tricky interpolation.&lt;br /&gt;&lt;br /&gt;If there is only one entry in the Key: section we just use that value.  If there are no Key: entries at all we use the default.  If there is not even a take: section for that LimbNode in the given Take, we create a new key frame and initialize it's default values to the LimbNode Lcl Rotation and Translation.&lt;br /&gt;&lt;br /&gt;This all happens in the Games Update section.  Many ModelTrackers can share the same Model.&lt;br /&gt;&lt;br /&gt;We also detect when the animation hits the end and provide a callback so the game can take action when the animation ends.&lt;br /&gt;&lt;br /&gt;Not yet implemented bu soon to come, tracking where a given LimbNode is in world coordinates so we can detect when a blade strikes an enemy. Update: This is done.  Turns out that on a LimbNode in Maya you can set arbitrary attributes, that then show up in the Properties60 section of the LimbNode entry.  We just set a property "Attack" and look for those and track them during attack moves.  Same for "Step" for tracking foot prints and putting prints in the snow.&lt;br /&gt;&lt;br /&gt;Also, KeyFrame sequences can be specified on any property, so we can put an animation on the value of a Attack Attribute and vary the attack deadliness through the attack swing.&lt;br /&gt;&lt;br /&gt;I have not yet accounted for the Initial Velocity Tangent and Final Velocity Tangent.  This allows for smoother blending between key frame segments.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-7947838891500737874?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/7947838891500737874/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=7947838891500737874' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/7947838891500737874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/7947838891500737874'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2008/09/fbx-and-xna-part-5-animation.html' title='FBX and XNA Part 5 - Animation Interpolation'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-8919893929308815696</id><published>2008-09-18T10:16:00.006-07:00</published><updated>2008-09-18T13:54:52.772-07:00</updated><title type='text'>FBX and XNA Part 4 - Drawing the model.</title><content type='html'>Now that we know what all the parts of the model are in the FBX, lets combine them.&lt;br /&gt;&lt;br /&gt;well,&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;for each Mesh in the Model&lt;br /&gt;make a copy of the Vertices&lt;br /&gt;make an array of Matrices, one for each point in the Vertices.&lt;br /&gt;They all get initialized to all &lt;span style="font-weight: bold;"&gt;zeros&lt;/span&gt; (not Identity)&lt;br /&gt;for each SubDeformer&lt;br /&gt;M = SubDeformer.Transform&lt;br /&gt;if it has any Indexes (some do not)&lt;br /&gt; find the animation in the current Take&lt;br /&gt;                     for this Deformer.&lt;br /&gt; It is the one in Connections that has the&lt;br /&gt;                     same name as the SubDeformer&lt;span style="font-family:Georgia,serif;"&gt;&lt;br /&gt;            M = M * the animation current rotation * the PreRotation *&lt;br /&gt;                                                             the animation current translation&lt;br /&gt;            if there is a parent LimbNode recursively do the&lt;br /&gt;                                                             M = M * rot * prerot * trans&lt;br /&gt;      remember m for this deformer.&lt;br /&gt;&lt;br /&gt; Now for all the remembered Ms influence the array of Matrices by&lt;br /&gt;doing weighted sums of the elements in the matrices. Note that&lt;br /&gt;this is not a matrix multiply,  it is an element&lt;br /&gt;by element weighted sum.&lt;br /&gt;vMats[Indexes[i]] += Matrix.Multiply(Transform, Weights[i])&lt;br /&gt;&lt;br /&gt;Now for every element in the copy of Vertices, do a matrix multiply by&lt;br /&gt;the weighted sum matrices&lt;br /&gt;to arrive at the position. Also do a TransformNormal to get the normals right.&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Phew, that is how its done.&lt;br /&gt;&lt;br /&gt;Now take the copy of Vertices that is now in world coordinates, and draw it on the screen.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;foreach Polygon in the list of polygon indices, call&lt;br /&gt;           GraphicsDevice.DrawUserPrimitives.  Like this&lt;br /&gt; gd.DrawUserPrimitives&lt;vertexpositionnormaltexture&gt;(PrimitiveType.TriangleFan, drawVerticesXformed, polys[i].StartIdx, polys[i].PrimCount);&lt;br /&gt;&lt;/vertexpositionnormaltexture&gt;&lt;/pre&gt;&lt;br /&gt;It's easy as that.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-8919893929308815696?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/8919893929308815696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=8919893929308815696' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/8919893929308815696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/8919893929308815696'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2008/09/fbx-adn-xna-part-4-drawing-model.html' title='FBX and XNA Part 4 - Drawing the model.'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-1876438112759211750</id><published>2008-09-18T10:16:00.005-07:00</published><updated>2008-09-18T13:41:01.650-07:00</updated><title type='text'>FBX and XNA Part 3 - Models cont.</title><content type='html'>Now we look at the &lt;span style="font-weight: bold;"&gt;LimbNodes&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;A LimbNode is a bone in the model. Just like your bones they have a length (translation) and an angle (rotation).  There is a section in LimbNodes called Properties60: and there are some important porperties.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Lcl Translation&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;Lcl Rotation&lt;/span&gt; are the default values to use for the limb if there is no animation information.  There is also a &lt;span style="font-weight: bold;"&gt;PreRotation &lt;/span&gt;which defines a transform on the limb before translation is added in. This is necessary because limbs may have rotation in the joint.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-weight: bold;"&gt;Deformer &lt;/span&gt;and &lt;span style="font-weight: bold;"&gt;SubDeformer &lt;/span&gt;are what connect the LimbNode to the mesh so the points in the mesh can actually be moved in world coordinates.  A Deformer is just the parent of one or more SubDeformers and is most important because it links (with the Connections: section) to the LimbNode.&lt;br /&gt;A &lt;span style="font-weight: bold;"&gt;SubDeformer &lt;/span&gt;simply has a series of indexes in the Vertices, and a series of weights.  In all our models if there are multiple deformers for a given Vertex, the sum of weights will be 1.0&lt;br /&gt;there also is a very important Transform.  The Transform is where the Deformer is relative to the LimbNode.&lt;br /&gt;&lt;br /&gt;I think we have all the pieces now.  Next we actually combine them to get a model that moves in world coordinates.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-1876438112759211750?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/1876438112759211750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=1876438112759211750' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1876438112759211750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1876438112759211750'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2008/09/fbx-and-xna-part-3-models-cont.html' title='FBX and XNA Part 3 - Models cont.'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-2378895293334455398</id><published>2008-09-18T10:16:00.004-07:00</published><updated>2008-10-01T14:43:36.951-07:00</updated><title type='text'>FBX and XNA Part 2 - 3D Models</title><content type='html'>The general file format of FBX is divided into sections.&lt;br /&gt;&lt;br /&gt;They are&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Header (ignored)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Definition (ignored)&lt;/li&gt;&lt;li&gt;Objects&lt;/li&gt;&lt;li&gt;Relations (ignored)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Connections&lt;/li&gt;&lt;li&gt;Takes&lt;/li&gt;&lt;li&gt;Version5 (ignored)&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Objects&lt;/span&gt;&lt;br /&gt;This is the data about the model.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Cameras (ignored) Things like Quicktime will use these to position the view when showing the model.  Quicktime is a great way to get a look at models, and "if it works in QuickTime then it should work in my code".&lt;/li&gt;&lt;li&gt;Mesh - The actual points that make up the model.  More on this later.&lt;/li&gt;&lt;li&gt;LimbNode - the Bones of the file.  These are definitions of the links between different parts of the mesh and Deformers and Animations.  Just like your body has a skin (the mesh) and bones (the LimbNodes).&lt;/li&gt;&lt;li&gt;Pose - (ignored) In modeling tools there are pre-done poses for the model.  You then animate as changes to the pose.  We ignore this since it only applies to tools that will be editing and changing  the model.&lt;/li&gt;&lt;li&gt; Deformer and SubDeformer - these are attached to the LimbNodes and tell which mesh points should be moved when the LimbNode moves, and by how much.  Several Deformers may influence a single mesh point to give smooth bends to the mesh around the joints.&lt;/li&gt;&lt;li&gt;GlobalSettings (ignored) If I ever see a model that has these changed I'll have to account for them.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Connections&lt;/span&gt;&lt;br /&gt;The connections section tells what the tree hierarchy is and which Deformers apply to which LimbNodes.  We use this alot when loading the model to get everything stitched together.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Takes&lt;/span&gt;&lt;br /&gt;Takes are the animations on the model. A single take is a single animation.  It has a range of time in some strange units that is an unsigned long.  I convert it to seconds by  a simple conversion factor until the speed looks right.&lt;br /&gt;The conversion is N / (1539538600.0 * 30.0) &lt;span style="font-weight: bold;"&gt;. &lt;/span&gt;Which may or may not be correct.&lt;br /&gt;In a Take are Keyframes for various values on a LimbNode.&lt;br /&gt;First there are the joints.  One section is the Transform where it says &lt;span style="font-style: italic;"&gt;Channel: "T" {&lt;/span&gt;&lt;br /&gt;Then in the section there is X, Y and Z.  There is a default value for each part, and then may or may not be keyframes with the tag Key:&lt;br /&gt;Key: entries are a series of values at given times.  The format is Time, Value, U, [s or a(?)], then if it was s there is a start velocity and end velocity (ignored), the the letter n.&lt;br /&gt;So an entry might look like this:&lt;br /&gt;              Key: &lt;span style="font-weight: bold;"&gt;1539538600,4.30184507369995,U,s,0,0,n&lt;/span&gt;,23093079000,4.30184507369995,U,s,0,0,n,46186158000&lt;br /&gt;                              ,4.30184507369995,U,s,0,0,n&lt;br /&gt;1539538600 is the start time of the first position, 4.3... is the value, since it is an s then the 0,0 are start and end velocity, and then the letter n.&lt;br /&gt;There is also a KeyCount that I should use in future versions for a more efficient load.&lt;br /&gt;&lt;br /&gt;Correction: Not really start and end velocity.  Actually the tangent of the velocity curve at the beginning and end of the segment, which is almost the same thing. In the future I will use these to get smoother animations.&lt;br /&gt;&lt;br /&gt;The only sections I use are the "T" section for translation, and "R" for rotation.&lt;br /&gt;&lt;br /&gt;A note on take: If the take has a Key: entry, then that determines the translation and rotation.  If it does not then you use the default values (Default: key).  If there is no animation for any LimbNode, than you have to fill in a dummy animation with the LimbNode Lcl Translation and Lcl Rotation as the default values.  Another way to do this would be to have the LimbNodes driving the drawing and looking to see if there is a corresponding animation data for that limb.  I could do it that way, but my code already is driven by the animations, so I create dummy animations for Limbs that don't have one.  After load and building the Mesh, Animation, and Deformers, I throw out all the other model data.  This is more compact.&lt;br /&gt;&lt;br /&gt;(Does any one know what "liw" stands for?)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Mesh&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The Mesh sections define the surface mesh of points in a model.  They are the basis of the model.&lt;br /&gt;the mesh has a Properties60: section that has lots of settings, all ignored.  But then there is the &lt;span style="font-weight: bold;"&gt;Vertices: &lt;/span&gt;section.  This is a list of X,Y,Z coordinates of all the points in the mesh and is often quite large. We read all these and keep them.&lt;br /&gt;&lt;br /&gt;Then is the &lt;span style="font-weight: bold;"&gt;PolygonVertexIndex:&lt;/span&gt; list.  This tells the index in Vertices of each point in a polygon on the model surface.  Obviously points often are part of several polygons, usually 4 since the vertices are the corners of rectangular patches.  The one trick here is that the end-of-polygon indicator is a negative sign on the index minus one.  What really happens is a -1 is XOR'd with the index.&lt;br /&gt;&lt;br /&gt;We ignore &lt;span style="font-weight: bold;"&gt;Edges: &lt;/span&gt;They are for showing the model as a wire frame which we never do.&lt;br /&gt;&lt;br /&gt;Another section is the &lt;span style="font-weight: bold;"&gt;Normals:&lt;/span&gt; section. These are the XYZ normals at the Vertices points.  This is used by the graphics processor to get the lighting shade correct when drawing the polygons.  There are two flavors, ByPolygonVertex, and ByVertex.  If it is ByPolygonVertex then every index in PolygonVertexIndex has a corresponding normal.  If it is ByVertex the each point in the Vertices list has a single corresponding normal.&lt;br /&gt;&lt;br /&gt;Next is &lt;span style="font-weight: bold;"&gt;UV:&lt;/span&gt; which is the texture coordinates.  A UV entry for a given Vertex is the X,Y location in the texture that corresponds to that point.  In a triangle of the mesh there will be 3 UV coordinates that form a triangle in the texture that is painted onto the triangle when it is drawn on the screen.  UV can also be ByPolygonVertex or ByVertex.&lt;br /&gt;The rest of the Mesh data gets ignored.&lt;br /&gt;&lt;br /&gt;When we read in the Mesh we convert it to a flat list of VertexPositionNormalTexture in XNA.&lt;br /&gt;Thus if it is a PerVertex Polygon and UV data it gets expanded out to PerPolygonVertex.&lt;br /&gt;&lt;br /&gt;Yikes, that's a lot of info.&lt;br /&gt;Next we talk about the other sections...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;TF&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-2378895293334455398?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/2378895293334455398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=2378895293334455398' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2378895293334455398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2378895293334455398'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2008/09/fbx-and-xna-part-2-3d-models.html' title='FBX and XNA Part 2 - 3D Models'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-1603614533333527741</id><published>2008-09-18T10:16:00.003-07:00</published><updated>2008-10-01T14:50:58.017-07:00</updated><title type='text'>FBX and XNA Part 1 - FBX Format and Reader</title><content type='html'>So you have an FBX file and want to read it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;FBX Encoding&lt;/span&gt;&lt;br /&gt;FBX files come in two flavors.  ASCII and Binary.  The ASCII format can be viewed in any text editor.  The binary format is more compact.  So far we only handle ASCII.&lt;br /&gt;&lt;br /&gt;The file is encoded as tagged fields.  For example, here is the definitions section of a file...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Definitions:  {&lt;br /&gt;Version: 100&lt;br /&gt;Count: 33&lt;br /&gt;ObjectType: "Model" {&lt;br /&gt;Count: 14&lt;br /&gt;}&lt;br /&gt;ObjectType: "Geometry" {&lt;br /&gt;Count: 3&lt;br /&gt;}&lt;br /&gt;ObjectType: "Material" {&lt;br /&gt;Count: 1&lt;br /&gt;}&lt;br /&gt;ObjectType: "Deformer" {&lt;br /&gt;Count: 12&lt;br /&gt;}&lt;br /&gt;ObjectType: "Pose" {&lt;br /&gt;Count: 3&lt;br /&gt;}&lt;br /&gt;ObjectType: "GlobalSettings" {&lt;br /&gt;Count: 1&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The Definitions: part is a tag, and what follows it is the values. In this case the value of Definitions: is a compound set of values.  The tag Version: is followed by a single value, 100.&lt;br /&gt;&lt;br /&gt;Some entries have both single values and compound values following a tag.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;The Parser&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;The parser is organized to read the general format of the FBX ASCII file but does not know what any of it means.&lt;br /&gt;The lowest level of the parser is the &lt;span style="font-weight: bold;"&gt;FbxWordReader &lt;/span&gt;class.  It knows how to read the next token in the FBX file. The method &lt;span style="font-weight: bold;"&gt;NextToken&lt;/span&gt; does this.  There is also a &lt;span style="font-weight: bold;"&gt;PushBack&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;SkipWhite&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Nodes&lt;/span&gt;&lt;br /&gt;The next level up is converting tokens into nodes in a tree, representing the hierarchy of the file.&lt;br /&gt;the base class is &lt;span style="font-weight: bold;"&gt;FbxNode&lt;/span&gt;, and it's two subclasses, &lt;span style="font-weight: bold;"&gt;StringNode, KeyNode &lt;/span&gt;and &lt;span style="font-weight: bold;"&gt;ListNode&lt;/span&gt;.  The StringNode is a single element that may be a string, integer, or float, or several other types, but at this level is always seen as a string.  The ListNode is a set of FbxNodes representing a compound entry.   The KeyNode is a key (tag) and then a series of values.&lt;br /&gt;These nodes know how to find sub-nodes (both single sub nodes, and lists of sub nodes.)&lt;br /&gt;&lt;br /&gt;The KeyNode knows about the key and it's values, and how to extract a Matrix.&lt;br /&gt;&lt;br /&gt;StringNode knows about String, float, int, ulong, time, and char.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-weight: bold;"&gt;FbxReader&lt;/span&gt; is the top level and does the recursive work of parsing the entire FBX file into a tree of nodes.&lt;br /&gt;&lt;br /&gt;Now we have the whole FBX file in memory, what does it all mean?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Partial Loads&lt;/span&gt;&lt;br /&gt;When we load a model we check to see if there is a subdirectory called Animations.  If there is we remove all the takes from the model, and load all the fbx files in Animations and extract their single take.  Then we rename the take to match the file name (e.g. Run.fbx get the take named set to Run) and insert it into the main model.  This way all our animations are single files in a subdirectory.  This is way easier on the modeler. Of course, we have to be careful that all bone names remain the same and such. We do this insertion in the FBX parsed tree before building the model in memory.&lt;br /&gt;&lt;br /&gt;TF&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-1603614533333527741?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/1603614533333527741/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=1603614533333527741' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1603614533333527741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1603614533333527741'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2008/09/fbx-and-xna-part-1-fbx-format-and.html' title='FBX and XNA Part 1 - FBX Format and Reader'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-9043057723321708806</id><published>2008-09-18T10:16:00.002-07:00</published><updated>2008-10-02T13:51:12.984-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FBX Format XNA 3D'/><title type='text'>XNA FBX and Custom Loader</title><content type='html'>At Sandswept Studios we are working on a Hack-n-slash side scroller.&lt;br /&gt;We were using the SkinnedModelProcessor but is had some problems.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Some models displayed all twisted up.  We then did lots of tweeks in Maya and sometimes it worked, and sometimes not.&lt;/li&gt;&lt;li&gt;We need our 3D modelers to be able to drop a model into the Content directory and immediately see the model in the game.&lt;/li&gt;&lt;li&gt;We need to Mix-n-Match meshes, animations, and textures.  For example, the player may change weapons.&lt;/li&gt;&lt;li&gt;We need to detect end of animation, movement of bones (LimbNodes) and such for in game event and attack/collision detection.&lt;/li&gt;&lt;li&gt;We need to be able to dynamically modify models meshes, for example, exploding monsters.&lt;/li&gt;&lt;li&gt;We need to be able to use the same texture between models.&lt;/li&gt;&lt;li&gt;We need to be able to strip the models of any unnecessary data so we have the smallest possible data set.&lt;/li&gt;&lt;li&gt;It has to run on the PC and the XBox.&lt;/li&gt;&lt;li&gt;When run on the XBox the FBX file should be pre-built into a binary format that reads really fast and is compact. (Not yet implemented)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Well, that's a tall order.  In short, we picked apart the FBX files format and learned how to load the ascii FBX file, and display the animated model on screen in the game.  There is a dearth of info on the FBX file format.  The next few posts here will be about how it is done.&lt;br /&gt;&lt;br /&gt;Shameless commercial plug: If you are interested in using our library in your game, contact me and we can arrange it.  We are thinking of a initial low fee to develop with the library, and a single lump sum when (and if) your game makes any money.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-9043057723321708806?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/9043057723321708806/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=9043057723321708806' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/9043057723321708806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/9043057723321708806'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2008/09/xna-fbx-and-custom-loader.html' title='XNA FBX and Custom Loader'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-6462568050666893580</id><published>2007-06-27T14:13:00.000-07:00</published><updated>2010-08-19T14:54:37.988-07:00</updated><title type='text'>Science is Hard</title><content type='html'>The raging debates on evolution and climate may have root cause that is unavoidable.  The fact is, science is hard.  You have to actually work and think clearly to understand what is going on. As you study an issue and delve deeper and deeper, your opinion can flip flop back and forth.&lt;br /&gt;&lt;br /&gt;My experience with climate issues has the following history:&lt;br /&gt;1970 - As a kid I was fascinated by the ice ages, and lived in Upstate New Your that is all glaciated terrain.  The belief then was that over the next several thousand years we would head back down into an ice age.  Cool!&lt;br /&gt;&lt;br /&gt;1990 - I was convinced that global warming was just hysteria.&lt;br /&gt;&lt;br /&gt;2005 - Even the cynic in Scientific American flips over to believing in global warming.  I'm fairly convinced it is happening.&lt;br /&gt;&lt;br /&gt;2006 - Saw the Al Gore Flick.  This was the turning point.  His data was so clearly flawed it was ridiculous.  Scientific data is never that clear.  Also his conclusion was completely wrong. The issue is not how to halt global warming.  The issue is how to deal with climate changes, both up and down.&lt;br /&gt;&lt;br /&gt;2007 - Searched really hard for real data and unpublished (mainstream press) theories. The revelation was this chart http://solarscience.msfc.nasa.gov/images/zurich.gif which clearly shows the little ice age.  More study showed that Dr. Mann's data used by Al Gore was seriously compromised.&lt;br /&gt;&lt;br /&gt;But here's the thing: Finding scientific data in the press is impossible.  I like to play a little game while reading articles on anything scientific.  The game is, find the hard facts in the article.  The vast majority of mainstream news articles have exactly zero facts.  They are all opinion and he-said, she-said.  Once in a while an article will have a single actual fact. &lt;br /&gt;&lt;br /&gt;So the only way were are left with is to dig for the data on the internet.  You can find the data but it is difficult.  You then have to back away from the data and take a good hard look at it and suspend preconceived notions and really look at the data.  What does it really say?&lt;br /&gt;&lt;br /&gt;Most of the people on the planet are not able to seek scientific truth by them selves.  First of all, they lack the education and training.  Second, the average IQ in the world is 100.  They just don't have the ability to figure things out.  That was ok when all we had to deal with was spears and saber tooth tigers, but falls flat on questions like global warming.&lt;br /&gt;&lt;br /&gt;So what would you estimate is the percentage of people on the planet that are able and willing to actually dig for real answers?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-6462568050666893580?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/6462568050666893580/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=6462568050666893580' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/6462568050666893580'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/6462568050666893580'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/06/science-is-hard.html' title='Science is Hard'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-1125483164063240108</id><published>2007-06-27T08:30:00.000-07:00</published><updated>2007-06-27T08:31:50.481-07:00</updated><title type='text'>Sunspots, Global Warming, Wobble of the Sun</title><content type='html'>This is a must read for all citizens of the world concerned about global warming.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://nzclimatescience.net/images/PDFs/alexander2707.pdf"&gt;http://nzclimatescience.net/images/PDFs/alexander2707.pdf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As the IMB sign used to say Think!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-1125483164063240108?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/1125483164063240108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=1125483164063240108' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1125483164063240108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1125483164063240108'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/06/sunspots-global-warming-wobble-of-sun.html' title='Sunspots, Global Warming, Wobble of the Sun'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-5273106371423883902</id><published>2007-06-18T13:02:00.000-07:00</published><updated>2007-06-18T13:35:25.550-07:00</updated><title type='text'>The Web Browser as Scapegoat</title><content type='html'>The arguments for Light weight client vs. heavy weight client come and go in cycles.  In management there is the adage: 'If things are going badly, reorganize!'  The parallel in software projects is 'If things are going badly, redesign!'&lt;br /&gt;&lt;br /&gt;One of the key technology issues in the last 30 years has been light weight vs. heavy weight clients. Back in the mainframe days, the only client was a green text only terminal.  The mainframe was the 'server'.  Then the workstation was invented and you could begin to move more processing to the client.  Engineers tried Sun Workstations or PCs as heavy clients and ran into exactly the same client management problems.  So you got the idea of a dumb client.  The dumb client ran X Windows and nothing else.  But that killed the bandwidth, so it was back to heavy clients. We had 2 tier, 3 tier, N tier, and lots of tears.&lt;br /&gt;&lt;br /&gt;Then along came the web server.  The browser was the new and fancier dumb client.  But that was slow so things swung back over to  the JavaScript enabled web browser.&lt;br /&gt;&lt;br /&gt;What is hidden in all these cycles is the fact that neither the thick client, nor the thin client was ever the problem.  What actually happened was that  a fad for one style would rise up as the silver bullet to fix all the current problems, and a new wave of naive engineers and managers would hop on the bandwagon.  After a few years the project would get in trouble,  after all, 80% of software projects fail, and the thick/thin client model was a convenient scapegoat.&lt;br /&gt;&lt;br /&gt;Management, trying to buy success, would hire in a new wave of engineers, who recommended the opposite of whatever client server model the old project had, and start all over.&lt;br /&gt;&lt;br /&gt;The actual solution was to manage the project better by applying more attention from management, and 'Get It Right (tm)'. &lt;br /&gt;&lt;br /&gt;With current computer systems, the difference between light weight clients, and heavy weight clients does not exist.  Yes that's a bold statement, but who could argue the IE or Firefox or Flash are light weight clients?  They are suitable for ALL applications short of first person shooters like Halo 3.&lt;br /&gt;&lt;br /&gt;The difference between IE, Firefox free clients and .NET/C# and Flex paid for clients is exactly that, you pay for the more bloated clients both in licensing and in development time and salaries.  Microsoft and others have a vested interest, with matching sales force, in convincing you that they have a better solution.  They also pander to managers who are under the delusion that you can buy success.&lt;br /&gt;&lt;br /&gt;What has remained constant is the pain associated with updating heavy client programs.&lt;br /&gt;&lt;br /&gt;On a recent project they went with a C# heavy client to 'fix all the problems' because they wanted to be able to display real time plotted data.  Ajax could have easily done it.  The slowness in the system was due to database contention, poorly written HTML/JavaScript,  and algorithms, not the web model. On another project management forced a switch from Ruby/Rails to Flex because they were the quintessential 'lets buy success' management team. (Also the Flex group had investment money which has all gone up in smoke now.)&lt;br /&gt;&lt;br /&gt;At this point for any business project the only sane choice is web based Ajax/HTML/XML.  If someone is pushing a heavy weight client, you can bet that they are either a sales person for Microsoft (.NET) or Flex, or has some other agenda related to 'fixing' the project.&lt;br /&gt;&lt;br /&gt;TF&lt;br /&gt;&lt;br /&gt;Footnote: The one place where heavy weight client still is viable is computer games or scientific visualization. Go XBox!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-5273106371423883902?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/5273106371423883902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=5273106371423883902' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/5273106371423883902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/5273106371423883902'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/06/web-browser-as-scapegoat.html' title='The Web Browser as Scapegoat'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-2807829288268986660</id><published>2007-06-18T11:56:00.002-07:00</published><updated>2008-09-18T14:49:25.396-07:00</updated><title type='text'>Solar Cycle Delay and Global Warming</title><content type='html'>My list of links that I view every morning includes &lt;a href="http://www.solarcycle24.com/solarimage.htm"&gt;SOHO, The Solar and Heliospheric Observatory&lt;/a&gt;, which has a set of images of the Sun updated frequently. The Sun right now has zero sunspots.&lt;br /&gt;&lt;br /&gt;Sunspots are dark places on the Sun where the magnetic lines have broken and loop above the Sun's surface.  There is an 11 year cycle of sunspots.  Over the cycle the number of sunspots increases and decreases. Sunspots start appearing near the poles of the Sun and gradually migrate south to the equator, then disappear.  There are fairly accurate records of daily sunspot counts going back to the 1700s.&lt;br /&gt;&lt;br /&gt;There is a hypothesis that when the sunspot cycle is reduced in amplitude, the Earth's climate cools.  The exact mechanism is not known, but might be due to the solar wind intensity.  When there are lots of sunspot you get much more particles being blasted off the Sun into deep space.  This wind may act as a shield against cosmic rays, which in turn effects high altitude clouds, which in tern makes the climate warmer or cooler.&lt;br /&gt;&lt;br /&gt;Back in the 1700s to 1840 the earth's climate was very cool and was called The Little Ice Age.  At that time the sunspot cycle was also markedly reduced. Europe had very cold long winters.  This is when Marie Antoinette said 'let them eat cake'. (Ok, she didn't actually say that.)  The peasants were starving due to crop failures.&lt;br /&gt;&lt;br /&gt;Right now the current sunspot cycle is delayed and may be a year late.&lt;br /&gt;&lt;br /&gt;There is also a theory based on the wobble of the Sun caused by Saturn and Jupiter.  This makes the Sun wobble around it's center and influences the sunspot cycle.  The theory predicts lower sunspot cycles starting in 2030 for a hundred years.  There are also several other competing and complementary theories of sunspot cycle drivers.&lt;br /&gt;&lt;br /&gt;We are right now on the cusp of getting real data as to whether sunspots influence climate much more heavily that CO2 levels.  If we have a drastic cooling in the next 20 years, then CO2 is not a factor.  If the sunspot cycle is greatly reduced, and the climate does not get cooler, then CO2 is the driving factor.  My bet is with a cooling.&lt;br /&gt;&lt;br /&gt;Current climate theories are very shaky both for and against Global Warming.  On the warming side the data is so heavily manipulated for political reasons that is is very difficult to trust any conclusions, especially from 'reputable global climate scientists'.&lt;br /&gt;&lt;br /&gt;The sunspot/global cooling theories the data seems to fit climate changes very well going back a very long time.  The number of sunspots yearly before 1700 can be estimated by isotope differences in ice cores and several other corroborating methods.&lt;br /&gt;&lt;br /&gt;The political climate is quite hot right now and make rational scientific discussion difficult and charged with name calling and governmental edicts.&lt;br /&gt;&lt;br /&gt;Luck for us, if we just wait about 20 years the answers will be much more clear.  If the next cycle amplitude is low then we may get some very chilling data in just the next 5 years.&lt;br /&gt;&lt;br /&gt;TF&lt;br /&gt;&lt;br /&gt;Update: Still no sunspots Sept 18, 2008.  Just a few very tiny 'pores' that show the field has reversed as it should, but no spots appearing.  Weird.&lt;br /&gt;&lt;br /&gt;TF&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://solarscience.auditblogs.com/2007/05/20/nasa-your-guess-is-as-good-as-ours/"&gt;Next Storm Cycle will Start Late&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://helios.gsfc.nasa.gov/cycle1.gif"&gt;Solar Cycles Back to 1700&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www-das.uwyo.edu/%7Egeerts/cwx/notes/chap02/sunspots.html"&gt;Sunspots and Climate&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.unisci.com/stories/20022/0613022.htm"&gt;Sunspots, Volcanoes, and Climate&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.research.noaa.gov/spotlite/archive/spot_sunclimate.html"&gt;Nice Graph of Sunspots vs. Climate (scroll down a page)&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-2807829288268986660?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/2807829288268986660/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=2807829288268986660' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2807829288268986660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2807829288268986660'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/06/solar-cycle-delay-and-global-warming.html' title='Solar Cycle Delay and Global Warming'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-2375972238194640027</id><published>2007-06-12T11:20:00.001-07:00</published><updated>2007-06-14T14:56:49.738-07:00</updated><title type='text'>MYT Rotary Engine</title><content type='html'>This is one of those Wow, Must See designs.  Very nifty.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.angellabsllc.com/animation.html"&gt;http://www.angellabsllc.com/animation.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-2375972238194640027?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/2375972238194640027/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=2375972238194640027' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2375972238194640027'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2375972238194640027'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/06/myt-rorary-engine.html' title='MYT Rotary Engine'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-1462575516713504202</id><published>2007-06-06T13:59:00.001-07:00</published><updated>2007-06-06T14:08:39.488-07:00</updated><title type='text'>Landmine Adds</title><content type='html'>We've put up with adds that grow bigger, adds that sucked up all our modem bandwidth, and adds that are just annoying, like the one from lowermybills.com with the cheesy crazy woman. Give-me-a-break!&lt;br /&gt;&lt;br /&gt;Now we have landmine adds.  These are adds that appear as a link (underlined) word on a page.  If you mouse passes over the link the add pops up (not a real popup, a CSS trick).  It only goes away if you click on the very tiny x button in the upper right corner.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tgdaily.com/content/view/32335/118/"&gt;Here is an example on tgdaily&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Are these sites and advertisers so clueless that they think their content is so great that such annoyances will not drive viewers away?&lt;br /&gt;&lt;br /&gt;We can thank &lt;span style="font-family:Verdana,Arial,Helvetica,sans-serif;font-size:-1;"&gt;Vibrant Media for this blight on the internet.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-1462575516713504202?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/1462575516713504202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=1462575516713504202' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1462575516713504202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1462575516713504202'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/06/landmine-adds.html' title='Landmine Adds'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-1089054520828864368</id><published>2007-06-05T08:46:00.002-07:00</published><updated>2007-06-06T12:05:32.601-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='omega omega3 fish oil depression anxiety'/><title type='text'>Fish Oil</title><content type='html'>At the risk of sounding like some fanatical evangelist, I'll do a book review and give some advice today.&lt;br /&gt;&lt;br /&gt;Several years ago I read a book called &lt;a href="http://www.amazon.com/exec/obidos/search-handle-url/102-4710105-7757730?%5Fencoding=UTF8&amp;search-type=ss&amp;amp;amp;amp;amp;amp;index=books&amp;field-author=Andrew%20Stoll"&gt;&lt;span style="font-weight: bold; font-style: italic;font-family:times new roman;font-size:100%;"  &gt;&lt;span class="sans"&gt;The Omega-3 Connection: The Groundbreaking Antidepression Diet and Brain Program &lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold; font-style: italic;font-family:arial;font-size:100%;"  &gt;by &lt;/span&gt;&lt;/a&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Andrew Stoll&lt;a href="http://www.amazon.com/exec/obidos/search-handle-url/102-4710105-7757730?%5Fencoding=UTF8&amp;search-type=ss&amp;amp;index=books&amp;field-author=Andrew%20Stoll"&gt;&lt;span style="font-style: italic;font-family:times new roman;" &gt;.&lt;/span&gt;&lt;/a&gt; &lt;/span&gt;This book discusses the use of Omega 3 fatty acids to increase vascular health and relieve depression.  The book was a miracle for me.&lt;br /&gt;&lt;br /&gt;For most of the first 3/4 of my life I suffered from anxiety attacks and panic attacks.  As a kid I did not recognize the attacks as such.  I just thought the things I was worried about were actualy normal things to panic about.  Much later I recognized the attacks as such.  Still there seemed to be no solution.  I chalked it up to genetics.&lt;br /&gt;&lt;br /&gt;A few years ago, while at the library, I felt inspired to pick out this book.  It discusses how hunter-gatherers eat lots of fish.  They got plenty of Omega-3 fats in their diet.  In the modern world we are very deficient in Omega-3s.  Cell walls are made of fats.  Whatever fats you have in your diet will get incorporated over time in your cell walls.  This effects two factors.  First is the flexibility of cell walls.  If you eat a preponderance of hard fats, your cell walls and thus arteries will be harder.  The second effect is that neuron cell walls follow the same rule, so the balance of fats will effect neuron activity.&lt;br /&gt;&lt;br /&gt;The result of having a sufficient quantity of Omega-3s is that your susceptibility to heart attack is decreased, and depression, anxiety, and such is decreased.  This change is related to cell wall composition, so there is a delay while the fats get replaced in cell walls.&lt;br /&gt;&lt;br /&gt;The two big sources of Omega-3 is fish oil, and flax oil.  I've tried both and now take 4 fish oil capsules a day.&lt;br /&gt;&lt;br /&gt;So the results.  After taking fish oil for about a week, I suddenly 'woke up'.  It was very strange.  Something happened that usually would have sent me off on a panic attack, and instead I was simply rational and calm.  No panic.  It was so obvious and clear that I was quite startled by the change.  After several weeks of fish oil I became accustomed to the new me.&lt;br /&gt;&lt;br /&gt;Several weeks later I forgot to take fish oil for a few days.  After a 3 day delay I suddenly had a panic attack right out of the blue.  It was the strangest thing because it was so blatantly obvious that is was almost funny.  Since I had not had a panic attack of any kind in weeks, I could clearly see it as such.&lt;br /&gt;&lt;br /&gt;It could be the Placebo Effect, but if it is, it's the best effect I've ever seen.  Also, there have been times since when I forgot to take the fish oil pills, and forgot that I forgot, and got hit by a panic attack.&lt;br /&gt;&lt;br /&gt;In Europe, if you have a heart attack, the hospital will &lt;a href="http://www.nytimes.com/2006/10/03/health/03fish.html?ex=1317528000&amp;en=1e953e11bac34784&amp;amp;ei=5088&amp;partner=rssnyt&amp;amp;emc=rss"&gt;prescribe fish oil&lt;/a&gt; when you leave.  It has been shown to reduce the chance of recurrences.&lt;br /&gt;&lt;br /&gt;So, where to get Omega-3s?  I buy the big bottle from Costco or WalMart.  You may need to try different brands to find one that is not 'fishy'.&lt;br /&gt;&lt;br /&gt;Human genetic variability is so broad that dietary advice for one person might not be applicable to another.  The whole Omega-3 thing has so much evidence that it should be worth a try.  I hope this article helps even one person to have a better life.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-1089054520828864368?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/1089054520828864368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=1089054520828864368' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1089054520828864368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1089054520828864368'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/06/fish-oil.html' title='Fish Oil'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-3375780028790449369</id><published>2007-06-01T13:48:00.001-07:00</published><updated>2007-06-06T12:06:25.372-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='diamond ring marriage love'/><title type='text'>A Rare Gem</title><content type='html'>&lt;div class="commentbody"&gt;                 &lt;p&gt;I bought my wife a diamond ring 20 years ago for our engagement.  This was before the 'blood diamond' days.&lt;/p&gt;  &lt;p&gt;It cost $750.  A month after we were married, while working on the concrete foundation for a back porch, the ring disappeared. The next 'diamond' ring she picked out was a cubic zirconia, and also cost seven fifty ($7.50).&lt;/p&gt;  &lt;p&gt;New diamond ring, $750, replacement fake ring, $7.50, my wife, Priceless.&lt;/p&gt;&lt;p&gt;TF&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-3375780028790449369?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/3375780028790449369/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=3375780028790449369' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/3375780028790449369'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/3375780028790449369'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/06/rare-gem.html' title='A Rare Gem'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-6026572105276080244</id><published>2007-06-01T13:48:00.000-07:00</published><updated>2007-06-01T20:53:02.795-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CFL'/><title type='text'>Compact Fluorescent Bukbs - Advice</title><content type='html'>Recently I have switched many bulbs to compact fluorescent (CFL) in my house.  Some advice from experience:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Always by just one of a bulb type to test it.  There is a huge variance in color, turn-on time, and such.  Try the new bulb and then if you like it, get more.&lt;/li&gt;&lt;li&gt;WalMart is convenient and has  good color CFLs.  1000bulbs.com is even cheaper but you have to order big batches of lights.  I got a bit burned because I ordered lots of lights, and a bunch were poor color.  So I'm not sure just which is a better way to go.  WalMart is better instant gratification.  Home Depot has very good prices and a very wide selection.  I have not bought from them yet, but they appear to be the good kind of bulbs.   WalMart now has a box of 12 for about $19.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Dimmable CFL's are awful.  When you dim a light you want a warm romantic glow.  Dimmable CFLs dim to a cold moonlight silver glow.  Uuuuuuuugly.&lt;/li&gt;&lt;li&gt;In bathroom lighting over sinks, use a mix of CFLs and the old Incandescent. This keeps the color balance correct for applying makeup.&lt;/li&gt;&lt;li&gt;Replace the high use lights first.  Or lights that the kids tend to leave on allot.  We have a basement closet where the little kids like to make tents out of blankets in, and the light sometimes gets left on for days.&lt;/li&gt;&lt;li&gt;Replace outdoor lights.  In very cold winter weather they take a few minutes to get fully lit, but are a huge energy user.&lt;/li&gt;&lt;li&gt;Color temperature is very important.  A normal light bulb is 2800 K degrees.  That is a nice warm light.  Try to get CFLs in the 2700K range.  They are called Warm White or Soft White.  The Cool White CFLs are harsher and more blue-white.  There supposed to be better for reading, but I don't buy them.&lt;/li&gt;&lt;li&gt;Today I bought a round vanity CFL at WalMart.  It is a good color and I mix it with old incandescent. Sure is easier on the eyes than those clear glass with filament kinds that are so annoying. Unfortunately if the whole vanity light bar was the round CFLs the color would not be acceptable.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Ignore the crap about Mercury in the bulbs.  One CFL is equal to about 100 cans of Tuna for Mercury content.  Besides, coal has Mercury in it and the lower energy use easily makes for less Mercury in the environment.  And you can recycle the Mercury in 10 years. If you break a bulb, just sweep it up and open a window to let any residual mercury vapor out.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Another thing I though of.  The CFLs I have installed will never get replaced with more CFLs. They will get replaced with LED lights that are even more efficient, and will have perfect color, and dim correctly.  They may also end up being slightly less expensive.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-6026572105276080244?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/6026572105276080244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=6026572105276080244' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/6026572105276080244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/6026572105276080244'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/04/compact-fluorescent-bukbs-advive.html' title='Compact Fluorescent Bukbs - Advice'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-6193275243560683483</id><published>2007-05-24T11:46:00.000-07:00</published><updated>2007-06-06T12:06:47.943-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='solar electric'/><title type='text'>Whats wrong with Solar Power</title><content type='html'>All my life I've been an alternate energy enthusiast.  As a teenager I built a 1Kw wind generator in my back yard.  It exploded in a blizzard. (cool!) I've build solar heaters, solar cookers and small solar electric panels.&lt;br /&gt;&lt;br /&gt;With all the recent articles about cheaper solar cells and such I went on-line and looked up what a home solar system actually costs.  Turns out it's not the solar cells that are the big cost.  It's the combined system.&lt;br /&gt;&lt;br /&gt;Here is the math I did.  Currently power is about 9 cents per kilowatt hour from the electric grid.&lt;br /&gt;&lt;br /&gt;(Prices and systems from http://www.wholesalesolar.com/indep.sys.html but this is &lt;span style="font-weight: bold;"&gt;not&lt;/span&gt; a cut against them.  They just seem to have the best systems and prices.)&lt;br /&gt;&lt;br /&gt;First a grid tie system.  This is a bunch of solar panels, and a controller, mounts, disconnect and such.  Ready-to-go.  The system is $14000 but there are rebates so lets say $10000.&lt;br /&gt;The solar cells are 2300 watts raw output.  Given a 5 hours average power per day, 6 days a week, 52 weeks a year, it comes out to 3,500,000 watt hours per year.  Divide the cost by 3.5 M and you get $2.78 per kilowatt-hour in one year.  Of course the system last 20 years so divide by 20 and you get 13.9 cents per kilowatt-hour.  Hmm, 1.5 times the cost of grid power.&lt;br /&gt;&lt;br /&gt;If the system breaks earlier, or needs repair the cost goes up.  One rock from a curious neighbor kid and the cost goes waaaaaay up. Also you can put the $10,000 in a CD and get about $200 per year.  In 20 years this is $4,000.  You could add this to the system cost so it is $14,000 instead of $10,000, raising the cost per kilowatt-hour, and you'd have the $10,000 left over at the end.&lt;br /&gt;&lt;br /&gt;The solar panels are $610 each and there are 18 of them thus $10,980.  The controller is $2,500.  Since it is a package deal they cut the cost a bit.&lt;br /&gt;&lt;br /&gt;Now lets assume the solar cells cut in half in price.  The panel price will not cut in half since it includes glass, frames, and such.  So we'll guess $3000 off the starting price, and after rebates you would save a bit less.  So lets assume $2000 savings.  Now the electricity over 20 years costs 11.1 cents per kilowatt-hour.  Getting closer.&lt;br /&gt;&lt;br /&gt;The same calcs on a battery off-grid system you could run your (very efficient) house on is 26 cents per kilowatt-hour because of all those batteries and power conversion. Here the solar cells base cost is $4880 or roughly half the system cost.&lt;br /&gt;&lt;br /&gt;Oh, and don't even think that when you move and sell your house you will get any of the cost of the system back.  It might even be viewed as a detraction from the value of the house. So you better live in the same house for 20 years.&lt;br /&gt;&lt;br /&gt;The point I'm trying to make here is that the solar cell cost is half to one quarter of the system cost.  The power controller and the batteries are most of the rest of the cost.&lt;br /&gt;&lt;br /&gt;What will bring down the cost of home solar power will be when the systems get mass produced and the cost of the parts comes down.&lt;br /&gt;&lt;br /&gt;The other issue with solar is the complete rejection of solar by utility companies via. regulatory obstruction. Don't think so?  Try &lt;a href="http://gristmill.grist.org/story/2007/5/23/122449/363"&gt;this article&lt;/a&gt;.   Then there are the local regulations.  The subdivision I live in has a flat out ban on any solar panels and wind generators.  The home owners association is a bunch of 'tree huggers' yet ban anything actually ecological because it might not look 'just right'.&lt;br /&gt;&lt;br /&gt;There is a bright side to this.  These systems are not increasing in cost, while electricity &lt;span style="font-weight: bold;"&gt;is&lt;/span&gt; increasing in cost.  If the states pass alternative power friendly laws in favor of solar installations, such as a law prohibiting home owners associations and towns from blocking installations, then solar could succeed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-6193275243560683483?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/6193275243560683483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=6193275243560683483' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/6193275243560683483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/6193275243560683483'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/05/whats-wrong-with-solar-power.html' title='Whats wrong with Solar Power'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-5184630476568095546</id><published>2007-05-23T08:33:00.000-07:00</published><updated>2008-12-12T21:53:12.076-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><title type='text'>Worrisome Bulge in Mt. St. Helens</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_tPxMCZtx__4/RlRf5c8-MgI/AAAAAAAAAAM/PUI9dlnCF0k/s1600-h/mtthumb.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://2.bp.blogspot.com/_tPxMCZtx__4/RlRf5c8-MgI/AAAAAAAAAAM/PUI9dlnCF0k/s320/mtthumb.JPG" alt="" id="BLOGGER_PHOTO_ID_5067780921327759874" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The &lt;span style="font-weight: bold;"&gt;US Forest Service&lt;/span&gt; announced today that the bulge in the summit crater of &lt;span style="font-weight: bold;"&gt;Mt. St. Helens&lt;/span&gt; has become a concern.  Such an unsightly bulge may be due to the age of the volcano and lower activity rates.&lt;br /&gt;&lt;br /&gt;The current weight loss plan include more frequent eruptions, and a reduction in input from the magma chamber below.&lt;br /&gt;&lt;br /&gt;A &lt;span style="font-weight: bold;"&gt;Dexatrim&lt;/span&gt;(tm) spokesperson says that this will be their most challenging client. A contender for the weight loss program was the well know &lt;span style="font-weight: bold;"&gt;Weight Watchers&lt;/span&gt;(tm).  An unidentified internal government worker was heard to say that 'Weight Watchers was not the lowest cost bidder, and the mountain would be unable to attend the weekly meetings.'&lt;br /&gt;&lt;br /&gt;The forest service will be using their aerial water drop planes to dump 500 gallons of Dexatrim per day on the mountain summit.&lt;br /&gt;&lt;br /&gt;Geriatrics specialist &lt;span style="font-weight: bold;"&gt;Dr. Friedman&lt;/span&gt; of the University of Utah Medical Center for Aging commented that the 1980 eruption seemed to due to comments by the Forrest Service about the volcano's weight.  After the eruption the mountain kept the weight off for a few years and is now gaining it back, plus a little more.&lt;br /&gt;&lt;br /&gt;&lt;span style=""&gt;Sarah &lt;b&gt;Ferguson&lt;/b&gt;, Duchess of &lt;b&gt;York&lt;/b&gt;&lt;/span&gt; commented that she had visited the volcano years ago and taken some pictures.  'It's not pretty to see an old friend let her self go like this, but I'm supportive and she is trying', quipped her highness.&lt;br /&gt;&lt;br /&gt;Mt. St. Helens was unavailable for comment as it is currently dormant.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-5184630476568095546?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/5184630476568095546/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=5184630476568095546' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/5184630476568095546'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/5184630476568095546'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/05/worrisome-bulge-in-mt-st-helens.html' title='Worrisome Bulge in Mt. St. Helens'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_tPxMCZtx__4/RlRf5c8-MgI/AAAAAAAAAAM/PUI9dlnCF0k/s72-c/mtthumb.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-820626409180687899</id><published>2007-05-16T09:40:00.000-07:00</published><updated>2007-06-06T12:07:37.328-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><title type='text'>'Microsoft Sold' is a misnomer</title><content type='html'>Once again Microsoft touts the 40 Million Vista sold number.&lt;br /&gt;&lt;br /&gt;But what does 'sold' mean in this context?  Does anyone really buy Microsoft's OS?&lt;br /&gt;&lt;br /&gt;Almost never.  It just comes pre-installed on the new machine you buy.  This is what being a monopoly does for a company.   You don't have to sell anything.  You just strong-arm the vendors of computers to include Vista, and forbid by contract the sale of XP, and so 'sales' of Vista skyrocket.&lt;br /&gt;&lt;br /&gt;So what do the numbers actually indicate?  That Microsoft has perfected their contracts to the point that the computer vendor have no wiggle room.  XP was adopted more slowly because cautions customers had a choice.&lt;br /&gt;&lt;br /&gt;Q1 2007 worldwide PC sales were 62 Million units.  Microsoft 'sold' 40 million Vista.  That's only 2/3 of the world PC sales, so maybe Microsoft needs to tighten it's legal grip even harder.  It would be nice to know what OS was on the other 20 Million units.  XP? Linux? Windows 98?  Pirated Vista?&lt;br /&gt;&lt;br /&gt;The truly interesting news is that Dell is allowing XP on some boxes due to customer demand.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.zdnet.com/microsoft/?p=438"&gt;http://blogs.zdnet.com/microsoft/?p=438&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.zdnet.com/ITFacts/?p=12669"&gt; http://blogs.zdnet.com/ITFacts/?p=12669 (11 Million / .176 = 62 Million)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-820626409180687899?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/820626409180687899/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=820626409180687899' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/820626409180687899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/820626409180687899'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/05/microsoft-sold-is-misnomer.html' title='&apos;Microsoft Sold&apos; is a misnomer'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-7133147398971872913</id><published>2007-05-15T21:26:00.000-07:00</published><updated>2007-06-06T12:07:58.108-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='siftware development business'/><title type='text'>US Software Industry Argues while Rome Burns</title><content type='html'>As things are now in the USA, Windows will never be displaced by Linux. Windows  is simply too entrenched.&lt;br /&gt;&lt;br /&gt;Such a monopoly will instead be overcome by becoming irrelevant in some other place, and then that place becoming dominant in some way.&lt;br /&gt;&lt;br /&gt;That place will be Asia, and Microsoft knows it.  A few years back China and several other Asian nations announced a project to replace the WinTel platform with a non-American platform.&lt;br /&gt;&lt;a href="http://www.japantoday.com/jp/news/293936/all" target="_blank"&gt;http://www.japantoday.com/jp/news/293936/all&lt;/a&gt;&lt;br /&gt;This includes an effort to replace the BIOS-Intel based hardware, and replace the operating system (Red Linux).&lt;br /&gt;&lt;br /&gt;The second step will be that China becomes the top economy in the world and can call the shots on an international scale. While the USA will have outdated WinTel platforms burdened by intellectual property fees, China et. al. will have a $50 box (India is talking about a $10 box) that out performs the old WinTel boxes in every measure.&lt;br /&gt;&lt;br /&gt;After this the computer hardware and operating system will be truly irrelevant.&lt;br /&gt;This is actually a good thing over all, just a very bad thing for the USA. We will finally have the dream of ubiquitous computers, and they won't be American made.&lt;br /&gt;&lt;br /&gt;The other way Microsoft is in trouble is from a further irrelevance caused by&lt;br /&gt;Google's office suite.&lt;br /&gt;&lt;br /&gt;Microsoft is acting like they know these things already.  They have just announced Vista + Office in a reduced version for $3 in the Orient.  This is a desperate attempt to try to keep the Asian countries on Windows.&lt;br /&gt;&lt;br /&gt;&lt;span style=""&gt;Violence (lawyers) is the last refuge of the incompetent.  - Isaac Asimov - &lt;/span&gt;&lt;br /&gt;and so Microsoft brings up the specter of patent issues.  This is monumentally stupid and will be detrimental to the future of computers in the USA.  While we (the USA computer industry) has hoards of lawyers fight out these issues, the rest of the world will just quietly laugh at us, and innovate. I hate to sound like some McCarthy era nut case, but what Microsoft is doing is Un-American.&lt;br /&gt;&lt;br /&gt;I tend to think globally and feel that the whole Us vs. Them is a bad viewpoint, the problem is that the contributions that the USA computer industry could&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;be making right now, is being squandered on the petty battles and skirmishes of irrelevant legal issues.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.theregister.co.uk/2007/04/26/microsoft_default_phenomenon/" target="_blank"&gt;http://www.theregister.co.uk/2007/04/26/microsoft_default_phenomenon/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.reuters.com/article/technology-media-telco-SP/idUSN1538059620070515"&gt;&lt;br /&gt;http://www.reuters.com/article/technology-media-telco-SP/idUSN1538059620070515&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;TF&lt;br /&gt;&lt;br /&gt;P.S.  Lookout for Africa next century.&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid coral; padding: 2em;"&gt;Historical Note: The USA used to own the world shipping industry.  Around 1900 the USA responded to global competition with extensive tariffs on foreign shipping.  The result was a trade battle, that the USA lost, and now ships are built in Greece and Korea.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-7133147398971872913?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/7133147398971872913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/7133147398971872913'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/04/us-software-industry-argues-while-rome.html' title='US Software Industry Argues while Rome Burns'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-1554181120814923235</id><published>2007-05-02T12:59:00.000-07:00</published><updated>2007-06-06T12:08:58.084-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drm'/><title type='text'>Ode to DRM</title><content type='html'>Ode to DRM&lt;br /&gt;&lt;br /&gt;A judicially predisposed junta&lt;br /&gt;barraged by puny computer junkies&lt;br /&gt;never had thought,&lt;br /&gt;only sued.&lt;br /&gt;&lt;br /&gt;For legal knuckleheads,&lt;br /&gt;in time baited user groups,&lt;br /&gt;molehills,&lt;br /&gt;first very small,&lt;br /&gt;upgraded greatly&lt;br /&gt;into insurmountable mountains.&lt;br /&gt;&lt;br /&gt;Amen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-1554181120814923235?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/1554181120814923235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=1554181120814923235' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1554181120814923235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/1554181120814923235'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/05/ode-to-drm.html' title='Ode to DRM'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-2761020531952175670</id><published>2007-05-02T10:24:00.000-07:00</published><updated>2007-06-06T12:08:24.154-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work adevice college'/><title type='text'>After College</title><content type='html'>A little advice for software engineers just graduating from college.  My son who is age 19 just got done with his first year at college in CS.  He just started his first real corporate job as an engineer/intern.  Sure brings back memories, so a little fatherly advice is in order.&lt;br /&gt;&lt;br /&gt;Your in for a big change in how you are treated.  All your life you have been surrounded by people that had a major interest in your success.  Parents, teachers, etc.  This is no longer true.  In the post-college world people are looking out for Number 1 and you are expendable.  Even that boss that wants to promote your career is doing it because that is what promotes the boss' career.  You will only be successful from here on out if &lt;span style="font-weight: bold;"&gt;you&lt;/span&gt; make it happen.  In my first job at Westinghouse I was put on the really sweet project that everyone wanted to be on.  One employee said to me, 'You are so lucky.'  I thought (but had enough tact not to say)  I make my own luck.&lt;br /&gt;&lt;br /&gt;Outcome Based Education is an big fad in schools, but has no relationship to reality.  In business, results matter, and effort plays a distant second.  If you try really hard and fail, you may get a sympathetic pat on the back, but you're also silently labeled a looser.&lt;br /&gt;&lt;br /&gt;You are now an equal to all those adults around you.  It is a real trip the first time you get introduced as Mr. or Mrs. So-and-so.  Don't let it go to your head.  Having just graduated from college, you have the latest ideas about how to do things.  Don't discount the years of experience those boring old guys have.  They have seen more computer fads come and go than you even know existed. (Remember 'visual programming' in 1993?) Make suggestions and explain nifty new ideas, but don't be snooty about it.&lt;br /&gt;&lt;br /&gt;When you start any new job, but especially your first one, you go through the phases of Initial Enthusiasm, The Doldrums, The Learning Curve, and then Productivity.  Just wait out the doldrums and work steady and hard.&lt;br /&gt;&lt;br /&gt;The absolute most important aspect of engineering is the &lt;span style="font-weight: bold;"&gt;interpersonal relationships&lt;/span&gt;.  It took me 15 years to learn this lesson the hard way.  As my sainted father once said, Never Burn Your Bridges.  Its amazing how that jerk you worked with ten years ago shows up working for a company you are interviewing with.  This works the other way too.  It is pleasantly amazing how the people you worked with 10 years ago pull you along into the really good start up companies.&lt;br /&gt;&lt;br /&gt;Seek a mentor in the company, not directly above you in the management chain, but higher up, and frequently ask for their advice. A little flatter here will go a long way. They can warn you of covert attacks from older experienced snipers in the company. Also, make relationships with people that have the skills you don't have.  If you are a complete computer nerd, make friends with a management charismatic type.  That is how great start up companies are made.&lt;br /&gt;&lt;br /&gt;Always be loyal to your boss and make the boss look good.  If you get a bad boss, have the mentor help you get moved (quickly).&lt;br /&gt;&lt;br /&gt;Always keep a resume out on line and up-to-date.&lt;br /&gt;&lt;br /&gt;Try to take jobs that are so interesting that the pay is secondary.&lt;br /&gt;&lt;br /&gt;Never get a secretary (oops, I mean Administrator) angry.  They run the company and can make your life miserable. An occasional bag of candy goes a long way.  In fact while were on the subject of candy, do something that is above the call of duty for everyone in the office.  I keep a bucket of candy on my desk.  It has brought me allot of good will and contacts that otherwise would not have been there. Keep your head up and looking around, not just buried in code.  Keep track of the big picture.  This makes for a good Halo player, and a good engineer.&lt;br /&gt;&lt;br /&gt;Start a contact list right now, even if you're currently 10 years old.  Have the name and address and phone number of everyone you ever talk to.  It comes in very handy if you suddenly get laid off.  I hear that Jimmy Carter's contact Rolodex fill two whole Rolodex.&lt;br /&gt;&lt;br /&gt;And the final advice: The only way to be successful is to have ownership.  Always keep an eye out and have some kind of spare time start up in the works. Take advantage of being young, single, and uprooted to take risks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-2761020531952175670?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/2761020531952175670/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=2761020531952175670' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2761020531952175670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2761020531952175670'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/05/after-college.html' title='After College'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-5750136766991320068</id><published>2007-04-21T09:59:00.000-07:00</published><updated>2007-06-06T12:08:44.280-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mom cellphone death'/><title type='text'>Deleting Mom's Phone Number</title><content type='html'>Mom died three months ago.  She died of Alzheimer's.  Probably the very worst way to die in the world.  Two weeks later my sisters and a few other relatives went to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Moline&lt;/span&gt;, Illinois to bury the ashes.&lt;br /&gt;&lt;br /&gt;The other day I was scrolling down my phone list on my cell phone and encountered Mom.  I stopped and stared at it.  Her number was still there.  What if I called it now?  Would Mom answer?  Could I tell her how her funeral went?  How the kids are doing?  Would she still tell me how proud she is of me?&lt;br /&gt;&lt;br /&gt;Menu, Down Arrow, Down Arrow, Down Arrow, &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;Delete&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Ok&lt;/span&gt; to delete?  Yes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-5750136766991320068?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/5750136766991320068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=5750136766991320068' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/5750136766991320068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/5750136766991320068'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/04/deleting-moms-phone-number.html' title='Deleting Mom&apos;s Phone Number'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-2667870150611980133</id><published>2007-04-20T22:55:00.000-07:00</published><updated>2007-04-20T23:21:42.947-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project management success buy'/><title type='text'>You Can't Buy Success in Projects</title><content type='html'>In many projects managers try to buy success.  The usual sequence is like this:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Management: We need a database. Which one should we use?&lt;br /&gt;Engineers: MySQL&lt;br /&gt;Management: Lets use Oracle because it is better and not a toy.&lt;br /&gt;Engineers: But Oracle is expensive, slow, a memory hog, feature bloated, and vendor &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;lockin&lt;/span&gt;.&lt;br /&gt;Management: But Oracle is the industry accepted standard.&lt;br /&gt;Engineers: It is a waste of money both in direct cost and more expensive DB admins salaries.&lt;br /&gt;Management: We have decided to go with Oracle, live with.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Now why is the decision really made this way?  The reason is that Management believes that paying lots of money makes Oracle more 'real'.  They are trying to buy success on the project. Management also &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;belives&lt;/span&gt;, but will not say so, that you the engineer are incompetent.&lt;br /&gt;&lt;br /&gt;The reality is that successful projects are not bought, they are managed and created.  So we get to the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Thundefist&lt;/span&gt; First Law of Projects:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-family:georgia;"&gt;The key element of success on a project is Pay Attention.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-family:arial;"&gt;Buying expensive solutions like Oracle, .Net, heavy metal servers, J2&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;EE&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;ClearCase&lt;/span&gt;, or any other proprietary solution will more likely hurt the project rather than make it successful.&lt;br /&gt;&lt;br /&gt;Throwing more bodies at a project is another style of trying to buy success. The worst version of this one is bringing in expensive consultants to 'fix things'.  Then the Expensive Consultant leaves and unfortunately takes his brain with him.&lt;br /&gt;&lt;br /&gt;A subtle form of trying to buy success is adding layer after layer of tracking, management, paperwork and such.  This is directly counter productive.&lt;br /&gt;&lt;br /&gt;A good manager will instead pay the real price of a &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;successful&lt;/span&gt; project, which is to spend actual time on the project engaged with the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_6"&gt;people&lt;/span&gt; and details of the project.&lt;br /&gt;&lt;br /&gt;There is a term for this management approach.  Hard Work.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-family:georgia;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-2667870150611980133?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/2667870150611980133/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=2667870150611980133' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2667870150611980133'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2667870150611980133'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/04/you-cant-buy-success-in-projects.html' title='You Can&apos;t Buy Success in Projects'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-7587258001962123177</id><published>2007-04-20T22:28:00.000-07:00</published><updated>2007-04-20T22:55:05.003-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby rails date_select with bracket id'/><title type='text'>Ruby on Rails date_select with bracket id</title><content type='html'>In Rails if you make a date_select in a rhtml file and put the empty brackets [] in the name, it goofs up the name.  You must add the &lt;span style="font-weight: bold;"&gt;:index =&gt; rec.id&lt;/span&gt; on the end of the method params to get the name correct.  Otherwise you get an error message like&lt;br /&gt;&lt;pre&gt;Couldn't find Child with ID=birthdate(1i)&lt;/pre&gt;For example:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;date_select('child[]', 'birthdate', {:index =&gt; child.id.to_s} )&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now in the controller things like &lt;span style="font-weight: bold;"&gt;Child.update(params['child'])&lt;/span&gt; will work.&lt;br /&gt;&lt;br /&gt;You also &lt;span style="font-weight: bold;"&gt;may &lt;/span&gt;need to get the date_helper.rb and time_helper.rb patch from &lt;a href="http://dev.rubyonrails.org/ticket/3811"&gt;http://dev.rubyonrails.org/ticket/3811 &lt;/a&gt;&lt;br /&gt;if you are not up to date with Ruby revs.&lt;br /&gt;&lt;br /&gt;TF&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-7587258001962123177?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/7587258001962123177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=7587258001962123177' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/7587258001962123177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/7587258001962123177'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/04/ruby-on-rails-dateselect-with-bracket.html' title='Ruby on Rails date_select with bracket id'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-2323627010636980001</id><published>2007-04-20T20:31:00.000-07:00</published><updated>2010-08-19T14:57:31.193-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='science religion mormon athiest'/><title type='text'>Science and Religion Crossover Points</title><content type='html'>&lt;span style="font-weight: bold;"&gt;&lt;div&gt;&lt;span style="font-weight: bold;"&gt;(Since writing this in 2007 I have become an Athiest. TF, Aug 2010)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;Crossover Points: &lt;/span&gt;Science has its ways of proving knowledge, and religion has its ways.  The current heated arguments between the two have to do with a difference of methods.  A crossover point is some issue or theory where religious ideas can be successfully proven by scientific methods. There are very few such points.&lt;br /&gt;&lt;div style="border: medium solid darkgreen; float: right; width: 30%;"&gt; There may also be crossover points the other way, where scientific theories can be proven by religions means. But that is not what this post is about&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;a href="http://en.wikipedia.org/wiki/The_scientific_method"&gt;The Scientific Method&lt;/a&gt;: &lt;/span&gt;Science proves ideas by analyzing evidence that can validate or invalidate in concrete ways.  All evidence must be viewable by several parties, all of which must be able to verify the evidence.  This may entail redoing an experiment and viewing the outcome, or looking at artifacts in an independent fashion. There is usually much discussion about the strength of  given piece of evidence, that results in a general consensus of validity.  After a time a consensus is reached and held until conflicting evidence arises, or a better 'fit' for the facts is discovered as a new theory.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Weak Religious Arguments: &lt;/span&gt;Most arguments presented by religious advocates fail in the 'all evidence must be viewable' and in the weakness of the evidence.  For example, a religious person might state that the spiritual feelings they have about &lt;a href="http://etext.virginia.edu/rsv.browse.html"&gt;The Bible&lt;/a&gt; prove it is the word of God.  This evidence is only valid to the person feeling it because no one else can see the feelings or spiritual witness.  In addition the feelings could be caused by many other mental effects and are thus not universally accepted as valid.&lt;br /&gt;&lt;div style="border: medium solid darkgreen; float: right; width: 30%;"&gt;Anyone else could read the Bible and get the same witness, but that will not validate the idea for people in general, and many people would say the evidence is just fooling your self&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;The recent article about the 18(?) invalid arguments given by religious believers (If anyone has a reference please email me) all the arguments made consist of self-reported evidence or of weak proofs.  For example 'my church must be true because everyone there is so nice' or 'God must exist or the Universe would not be here.'  This article was a good list of bad arguments and every one was correct in that none of the arguments are valid from a scientific view.  Thus none of them are crossover points.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Synthetic Crossover Points: &lt;/span&gt;Some religious arguments attempt to create crossover points by either distorting scientific theories (&lt;a href="http://en.wikipedia.org/wiki/Inteligent_design"&gt;Intelligent Design&lt;/a&gt; (yuck), or Evolution is 'just a theory') or citing evidences that are too weak.  A classic series of weak arguments are proofs that the Bible is the infallible word of God, and then trying to disprove scientific theories by the Bible.  If the base evidence (The Bible) is weak as a proof, then all the rest of the arguments fall down.  I have yet to see a verifiable proof that the Bible is the word of God.&lt;br /&gt;&lt;div style="border: medium solid darkgreen; float: right; width: 30%;"&gt;On the other hand, I do believe that the Bible is inspired by God, but all my direct proofs or of the internal weak type. More on this later.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Written Artifacts: &lt;/span&gt;The most obvious crossover point would be a written artifact of know age and origin.  The Bible is a written artifact, but is obviously an evolved text over many centuries.  While the Bible is interesting and useful, it is not miraculous in any verifiable sense. Its existence can be entirely reasonably accounted for by archaeological, social, and historic means.&lt;br /&gt;&lt;br /&gt;What alternative artifacts or evidence could there be? Other verifiable evidences for the existence of God would be a repeatable and measurable miracle.  I have never seen such a thing, and in fact most religious doctrines state that 'tempting God' for a repeatable miracle, on demand, is against the way religion works. (You evil sinner you!)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Main Point:&lt;/span&gt; So now we arrive at my main point.  The only crossover point I have ever seen is the &lt;a href="http://scriptures.lds.org/bm/contents"&gt;Book of Mormon&lt;/a&gt;.  Several ideas surrounding  The Book of Mormon and the Mormon doctrinal story about where it came from are not crossover points.  The part about the angel delivering the gold plates and similar ideas are not scientifically verifiable.&lt;br /&gt;&lt;br /&gt;What is verifiable is the concrete text and it's claim to be of ancient semi-Hebrew origin and partly of Egyptian literary and cultural origin.  Regardless of the spiritual claims made by Mormons about the Book of Mormon, in no way do such claims invalidate the concrete textual reality.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Facts of Origin:&lt;/span&gt; There are several concrete facts about where The Book of Mormon came from.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Note: I will be referring to The Book of Mormon, meaning the written of the text on paper with a pen by normal people and its publication on a printing press as a commonly available printed book.&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The Book of Mormon was not in existence before the early 1800's&lt;/li&gt;&lt;li&gt;There is a very small pool of people that were involved in the creation of The Book of Mormon.  It was not a huge group collaboration.&lt;/li&gt;&lt;li&gt;Egyptian was not yet translatable when The Book of Mormon was created.&lt;/li&gt;&lt;li&gt;The Book of Mormon first edition is available.  Since then revisions have been very minimal punctuation changes and a few word changes for clarity.  Thus the current edition is valid for analysis.&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Thesis: &lt;/span&gt;If The Book of Mormon can be shown to have linguistic, cultural, and literary artifacts that show it be a combination of Hebrew and Egyptian text, translated (not &lt;a href="http://en.wikipedia.org/wiki/Transliterate"&gt;transliterated&lt;/a&gt;) to English, then it is a concrete, verifiable evidence of the existence of God.  In Mormon parlance, it is 'A Marvelous Work and a Wonder'.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-2323627010636980001?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/2323627010636980001/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=2323627010636980001' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2323627010636980001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/2323627010636980001'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/04/science-and-religion-crossover-points.html' title='Science and Religion Crossover Points'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-960296322531827746.post-9102268089716768615</id><published>2007-04-20T16:41:00.000-07:00</published><updated>2007-04-20T22:42:25.543-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='microsoft marketing vista silverlight'/><title type='text'>Microsoft Marketing Disaster</title><content type='html'>&lt;div&gt;&lt;span class="494315721-20042007"&gt;&lt;span style=";font-family:Arial;font-size:85%;"  &gt;&lt;br /&gt;This week had the  privilege of sitting through a presentation given by a Microsoft Field Engineer  about Vista to a room full of software engineers.  The intent of the  presentation was to generate enthusiasm for Vista and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Silverlight&lt;/span&gt;.  The  presentation started out with about 7 slides telling us how exciting Vista  is.  None of the slides said anything about actual features, just repeated  how exciting it is.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span class="494315721-20042007"&gt;&lt;/span&gt; &lt;/div&gt; &lt;div&gt;&lt;span class="494315721-20042007"&gt;&lt;span style=";font-family:Arial;font-size:85%;"  &gt;Then they finally  showed slides of actual features.  The first feature, and the most  impressive, was the new look.  The windows are prettier, the buttons  rounder and the backgrounds are nearly black. Then the next most important  feature was that you can show all the windows in a 3D view as pages you can flip  through.  The third feature was that while editing text the text change  dialog will &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;popup&lt;/span&gt; right next to where the mouse is.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span class="494315721-20042007"&gt;&lt;/span&gt; &lt;/div&gt; &lt;div&gt;&lt;span class="494315721-20042007"&gt;&lt;span style=";font-family:Arial;font-size:85%;"  &gt;That's it.  The  three top features and improvements.  We were underwhelmed.  Their key  tag line on their Vista page is 'Crank up the Wow'.  Since when do you have  to tell your audience that what you have is exciting?  Compare this to the  marketing approaches of Apple.  When they announced the first &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;iPod&lt;/span&gt;, Jobs  simply stood on a huge barren stage, pulled out an &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;iPod&lt;/span&gt; and demonstrated it to  the audience.  The audience when hysterical.  There was no need to  tell anyone to get excited. For developers Linux is exciting because it is wide  open.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span class="494315721-20042007"&gt;&lt;/span&gt; &lt;/div&gt; &lt;div&gt;&lt;span class="494315721-20042007"&gt;&lt;span style=";font-family:Arial;font-size:85%;"  &gt;I then started to  contemplate how irrelevant Windows Vista is, and quickly realized that Vista is  not at all irrelevant.  The problem is that Vista is relevant for all the  wrong reasons.  Vista will be the dominant OS because Microsoft will use  it's dominant position to force Vista on users.  The end users have no  say in what OS they use.  If they are a home user it is simply what comes  on the box &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;preinstalled&lt;/span&gt;, and corporate users are forced to use what the company  standardizes on. (Yes you can be a maverick, but that can be a career limiting  move, or limit what games you can play at home.)  Apples products are  relevant because they are interesting and desired by end users.  Google is  relevant for the same reasons.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span class="494315721-20042007"&gt;&lt;/span&gt; &lt;/div&gt; &lt;div&gt;&lt;span class="494315721-20042007"&gt;&lt;span style=";font-family:Arial;font-size:85%;"  &gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Silverlight&lt;/span&gt; is a  Flash &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;wanabe&lt;/span&gt;.  During the demo of the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Silverlight&lt;/span&gt; the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;IDE&lt;/span&gt; failed.  The  engineer tried to drag-n-drop an element and the machine froze.  This  leaves an engineering group with the problem of choosing Flash, which is well  proven, functional, and ubiquitous, or to choose &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Silverlight&lt;/span&gt;, be guinea pigs for  the Beta &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;IDE&lt;/span&gt;, and hope that in the future Microsoft does not drop &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;Silverlight&lt;/span&gt; on  some marketing whim. Of course, Microsoft realizes that the engineers don't  make the buying decision.  Top management is the one to sell to, behind  closed doors.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span class="494315721-20042007"&gt;&lt;/span&gt; &lt;/div&gt; &lt;div&gt;&lt;span class="494315721-20042007"&gt;&lt;span style=";font-family:Arial;font-size:85%;"  &gt;I'm old enough to  remember clearly the good old days when IBM had a dominant position in the  computer market, and for the exact same reasons given above, lost  it.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span class="494315721-20042007"&gt;&lt;/span&gt; &lt;/div&gt; &lt;div&gt;&lt;span class="494315721-20042007"&gt;&lt;span style=";font-family:Arial;font-size:85%;"  &gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;TF&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/960296322531827746-9102268089716768615?l=thunderfist-podium.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thunderfist-podium.blogspot.com/feeds/9102268089716768615/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=960296322531827746&amp;postID=9102268089716768615' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/9102268089716768615'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/960296322531827746/posts/default/9102268089716768615'/><link rel='alternate' type='text/html' href='http://thunderfist-podium.blogspot.com/2007/04/microsoft-marketing-disaster.html' title='Microsoft Marketing Disaster'/><author><name>Thunderfist</name><uri>http://www.blogger.com/profile/09250922155411121357</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_tPxMCZtx__4/TMcDzXKsgpI/AAAAAAAAAB0/fghS3Ukr4_0/S220/rk.jpg'/></author><thr:total>0</thr:total></entry></feed>
