text:
tag:blogger.com,1999:blog-43662778843018898872016-05-06T22:27:07.217-07:00I learned something todayI program Android in C++.Ianhttp://firstname.lastname@example.com:blogger.com,1999:blog-4366277884301889887.post-81518926836527708862012-01-18T07:29:00.000-08:002012-01-18T07:56:16.762-08:00Darkness on the InternetToday is Stop SOPA day, with sites like Wikipedia going dark in protest. Google isn't going dark, but it's got a doodle about it, so you know it's got to be at least as important as, say, Doraemon.

Please take a moment to sign a petition or contact your congressperson about SOPA and PIPA. This is a complicated issue and there are two sides to every argument, but as an internet user I feel SOPA is a horrible idea.

To understand why SOPA is a bad idea, consider this analogy. Let's say I call you up on your T-Mobile phone, and leave you a voicemail. (I'll use voicemail as an example because it's stored on T-Mobile's servers.) As part of my voicemail message, I play you a bit off my new Lady Gaga CD. (I have to use Lady Gaga as an example, because I work for Google. Long story.) Let's assume for the sake of argument that this is illegal. Who is at fault?

Am I at fault for playing the song? To the extent that playing it was illegal, I'd say yes. Absolutely, I'm at fault. Punish me.

Are you at fault for listening? You know what, I'll bite. Let's punish you, too--you should have hung up as soon as you realized there was unauthorized Gaga on the line.

Is T-Mobile at fault for storing my voicemeil? Think for a minute about what that means. How exactly was T-Mobile supposed to prevent this infringement? There's only one way: eavesdropping on every single voicemail that is ever left by anyone that uses their system.

Quite aside from the privacy concerns, this is a logistical nightmare. They'd have to have an army of people listening in on every conversation that anyone ever made, ready to flip a kill switch the moment they heard "Poker Face." And that's an easy example. What if the infringement involved someone less famous, like Elvis Hitler or Toad the Wet Sprocket? What if I am Elvis Hitler, and I'm playing you a track from my long-awaited followup to "Disgraceland?" There's going to be a lot of judgment calls, and a lot of eavesdropping.

Now let's talk about punishment. In this analogy, SOPA would not only require T-Mobile to do the eavesdropping and make the judgment calls. It would also allow any entertainment company to shut off T-Mobile completely just on the allegation that infringement occurred. Until it proved itself innocent, T-Mobile would be unable to connect to the U.S. telephone system or use U.S. airwaves. (In this analogy I'm granting the government miraculous powers over the electromagnetic spectrum--which, if you think about it, is not much more far-fetched than the miraculous powers it would need to have in order to actually enforce SOPA the way Congress apparently thinks it can.)

Think about that for a minute: an entire company put on hold on the basis of an allegation by some media multinational. Millions of employees out of work. Tens of millions of customers who can no longer communicate. All in the name of stopping infringment.

Replace "T-Mobile" with "YouTube," "Facebook," or "Google" and that's SOPA.

Listen, I don't want to come across as a big leftie here, but here in America we don't shut companies down even when we have solid proof that they are killing people. Now we're talking about shutting down Internet businesses not because they did something wrong, and not even because we have proof of wrongdoing, but because some entertainment company alleged that that one of that company's customers did something that might be wrong.

And don't even get me started on the actual enforcement clauses, which would empower our government to set up its own Great Firewall. I don't want to sound like Glenn Beck, but folks, this is how liberty ends. Ask a Chinese friend what the Great Firewall is for. Unless they're really dialed into politics, chances are they'll tell you it's to keep out porn and terrorists. We in the West think we'd never stifle political dissent, but we'll do it in a heartbeat if instead of calling it "dissent" you call it "terrorism" or "indecency" or "infringement."

Whatever you think about copyright law, SOPA is not the right way to enforce it. Even if the entertainment industry is right (newsflash: they're not) and a lack of SOPA would cause the entertainment industry to wither up and die, would we really censor the entire Internet in order to keep those Jerry Bruckheimer movies coming every summer? Ben Franklin derided those who would trade liberty for safety. What would he think of those who ask us to trade essential liberties for continued access to mindless entertainment?

So please, contact your congressperson. Wikipedia has a search tool to help you. Don't copy a form letter, write something short and succint and from the heart. Even if it's just a few words, write something. If you're an avid Internet user, SOPA is literally an attack on your way of life. Help put a stop to it.Ianhttp://firstname.lastname@example.com:blogger.com,1999:blog-4366277884301889887.post-66360420497072737862011-11-28T13:38:00.001-08:002011-11-28T13:43:08.580-08:00My first "official" Android Blog post......went live last week here! It's about my own personal pet peeve, games that play audio when you're not playing them. One of my achievements this year has been to improve the technical standards for featuring on the Android Market; at this point, it's almost impossible to get a new title featured if it has this bug. Which means, of course, that part of my job is to send off emails to promising game developers, asking if they can fix this sort of issue so that we can feature their game. I'm hoping that publishing this sort of blog post will help.

Stay tuned for more; in return for being allowed to title my post "Part I of a series," I had to commit to at least three more episodes. :-)Ianhttp://firstname.lastname@example.com:blogger.com,1999:blog-4366277884301889887.post-92021407726604408582011-09-19T12:13:00.000-07:002011-09-19T12:55:50.073-07:00Bug in LockFreePipeDmitry Vyukov, one of my fellow engineers at Google, pointed out a bug in the implementation of LockFreePipe that you can find here and there on the internet, for example here. That reminded me that Bruce Dawson (who coauthored the original with me) had discovered this bug a while ago and tried to explain it to me, but at the time we didn't have the code in front of us and I didn't completely grok what he was trying to tell me.

Anyway, this particular bug is simple: in Read(), after the call to memcpy(), there should be a barrier before the read pointer is updated. Otherwise the read pointer update can become visible before the memcpy is finished, giving the writer an opportunity to overwrite the memory before it's read.

 unsigned long cbTailBytes = min( bytesLeft, c_cbBufferSize - actualReadOffset );
#ifdef _XBOX_VER
 XMemCpy( pbDest, m_pbBuffer + actualReadOffset, cbTailBytes );
#else
 memcpy( pbDest, m_pbBuffer + actualReadOffset, cbTailBytes );
#endif
 bytesLeft -= cbTailBytes;

 if( bytesLeft )
 {
#ifdef _XBOX_VER
 XMemCpy( pbDest + cbTailBytes, m_pbBuffer, bytesLeft );
#else
 memcpy( pbDest + cbTailBytes, m_pbBuffer, bytesLeft );
#endif
 }

// OOPS: no barrier here. These operations could be reordered

// by the compiler or by the CPU. Should have lwsync or _ReadWriteBarrier here.
 readOffset += cbDest;
 m_readOffset = readOffset;

Dmitry also pointed out that a store-release is meaningless without a load-acquire, so there should also be a barrier in Write() after m_readOffset is read:

 bool __forceinline Write( const void* pvSrc, unsigned long cbSrc )
 {
 // Reading the read offset here has the same caveats as reading
 // the write offset had in the Read() function above.
 DWORD readOffset = m_readOffset;

// OOPS: need lwsync or _ReadWriteBarrier here if we want it to work
 DWORD writeOffset = m_writeOffset;

Needless to say, I'm humiliated :-) and curious to know why this worked so well in the past. My first guess was that MSVC did not reorder because the read pointer was marked volatile. Of course, that raises the question of whether any of our barriers were necessary, if volatile is so magic. Well, yes, they were; MSVC volatile semantics at the time prevented compiler reordering, but didn't insert any barriers at the CPU level. The write could still have become visible any time before the read was issued. So why didn't it?

I'd say we got lucky. Just because the CPU can reorder stores before reads, doesn't mean that it does. There's a good reason for the PowerPC to delay stores--it's something that can usually be deferred until later, because in general nobody's really waiting for a store to complete. (If the data is getting reused, it's probably in one of the PPC's copious number of registers. And if it's not... see "load-hit-store.") There's seldom a good reason for a read to get delayed, because the read is very frequently a dependency of the next instruction in the queue. I'm speaking very generally and in a fashion that involves waving my hands quite a lot, but the point is that the window for failure on this is pretty small. Not, however, small enough to be nonexistent, which is what you need if you're doing lock-free work. Bummer.

The sad thing is that I really like this class. It's small and lightweight, doesn't do any allocation, and is basically perfect for things like passing data in and out of audio routines where blocking would cause glitches. I originally wrote it to dump sample data out of custom DSP routines on the Xbox 360, and it worked awesomely well for that purpose. But after talking to Dmitry, I realize that it really only worked as well as it did because of quirks in the 360's CPU architecture. It's not a generic piece of code.

In any case, if you're using this class, please fix it by inserting memory barriers as described in the code snippet above. And stay tuned--there may be other bugs that I haven't found yet.Ianhttp://firstname.lastname@example.com:blogger.com,1999:blog-4366277884301889887.post-69816518703752336952011-09-10T17:35:00.001-07:002011-09-10T17:35:45.200-07:00My current frustration

Ianhttp://firstname.lastname@example.com:blogger.com,1999:blog-4366277884301889887.post-78837348714239706042011-09-06T14:00:00.000-07:002011-09-06T14:00:03.137-07:00Checking In...I haven't been good about posting to this blog lately, probably because I originally started it to talk about the Android NDK, and I haven't been doing much of that lately. I've been jumping around to different parts of Android, trying to learn more about the entire system. But I've made what Tim Bray says is a fundamental blogging mistake, which is to only write about what you think your audience wants to hear. Oops. I guess I should really start writing about what I've been doing, whether or not it's NDK-related (or even Android related).

What I've mostly been working on, besides the inevitable "partner support" email queue, is a Google Tasks app. Yeah, I know, not groundbreaking. But all of the apps I've found so far do it wrong. They don't authenticate with my Google account token--instead, they ask me for my actual Google credentials, which I'm not going to give them. And they don't sync correctly. I want a Tasks app that's as solid as the Gmail app, and since I have the code to the Gmail app, I think I ought to be able to do it. I've got most of the account management stuff worked out, and I have access to the GTasks API (which is, by the way, kind of incomplete), and now I'm writing a ContentProvider so that I can hook it to a SyncAdapter and make background sync work. That's taken me down a path of inventing a lightweight ORM so that I can write a ContentProvider without having to do a whole lot of redundant keyboarding. (I almost said "typing," but that's an overloaded term in this context.)

So that's probably what I'll be writing about for the next little while: my quixotic attempt to do a simple Android app The Right Way. I want it to be a shining example in every possible way. I've already found a few places where that's going to be impossible, because no Right Way exists. But that's a subject for another post...Ianhttp://email@example.com:blogger.com,1999:blog-4366277884301889887.post-6517514504233782352011-08-08T15:00:00.000-07:002011-12-01T15:07:31.586-08:00Ndk-gdb and service processes don't (currently) mix
Got a bug from one of our partners complaining that they had two almost identical Android projects, but one of them was debuggable and the other one wasn't. After checking all the usual culprits, we finally narrowed it down to a single line in the manifest of the undebuggable project (names have been changed, obviously):

<service android:name="com.somemiddleware.SomeUsefulService" android:process=":com.somemiddleware.useful.process" />

It was, of course, very tempting to blame the SomeMiddleware company and its purportedly Useful service, but it wasn't their fault at all. Instead, it turned out to be a very small error in one of the ndk's awk scripts. It turns out that the script that finds the pid of the process you're supposed to be debugging (extract-pid.awk) was, for various reasons, doing a substring match on the process name. This almost always works, because there's almost always only one process running under your package name at any one time. But it doesn't always work.

In this case we were bitten by a quirk of the Android service architecture. The manifest is allowed to specify a process name under which to run the service by using the android:process attribute. Normally this just specifies the exact name of the process that the service should run under. But there's a special case: if the process name so specified begins with a colon, then the service process is considered "private" and its name is concatenated with that of the main process. So instead of running as "com.somemiddleware.useful.process" the service runs as "com.mycompany.mygame:com.somemiddleware.useful.process."

See the problem? Now we have two processes that match our package id: our main game process that runs as "com.mycompany.mygame" and the middleware service that runs as "com.mycompany.mygame:com.somemiddleware.useful.process" -- and guess which one gets matched by the ndk-gdb awk script?

The fix to extract-pid.awk is simple, and I've already submitted a patch, so hopefully that'll get accepted and shipped in the next NDK. Meanwhile, if you happen to run into this bug, you can either patch the script yourself, or you can just eliminate the colon from the beginning of your service process name while you're debugging.

If you're interested, here's a gnu diff version of the patch:

25,27d24

< # NOTE: For some reason, simply using $9 == PACKAGE does not work

< # with this script, so use pattern matching instead.

< #

31a29

> RS = "\r\n"

40c38

< gsub("\\.","\\.",PACKAGE)

---

> #gsub("\\.","\\.",PACKAGE)

46c44

< $9 ~ PACKAGE {

---

> $9 == PACKAGE {

Ianhttp://firstname.lastname@example.com:blogger.com,1999:blog-4366277884301889887.post-57190924911157302252011-07-12T11:33:00.000-07:002011-07-12T11:33:56.278-07:00Yes, I am now on Google+Of course.Ianhttp://email@example.com:blogger.com,1999:blog-4366277884301889887.post-31483212464596897992011-07-08T10:38:00.000-07:002011-07-08T10:38:37.106-07:00Anyone want to do some Android ports?A friend of mine is looking for a team to port a couple of titles to Android. Email me if you're interested: i lewis at google dot com.Ianhttp://firstname.lastname@example.com:blogger.com,1999:blog-4366277884301889887.post-16173031869135922232011-05-27T08:36:00.000-07:002011-09-06T13:49:14.354-07:00I'm slowly learning to hate Eclipse lessI'm doing more development on my Mac, which means more Eclipse. Of course I hate it. I've been using Visual Studio since 1998, and Turbo C++ before that, and compared to those IDEs Eclipse feels like... well, it feels like Linux. There's no better way to put it. It feels like a hodgepodge of great ideas put together by a large number of incredibly smart people with almost no coordination whatsoever.

Fortunately I work with a large number of people who are both smarter and more patient than myself, so I was able to get help. Fred Sauer, better known as one of the minds behind Angry Birds Chrome, sat down and shared some tips that ended up making a huge difference to me. Here's a selection of the tips that helped me the most:

Eclipse "workspaces" are pretty much just like Visual Studio solutions. They seem different and weird at first, because (a) they're directories, not files, and (b) Eclipse makes you choose one at startup. But end of the day, they're just containers for projects.

"Close Unrelated Projects" is the magic command to unclutter your workspace--it closes up every project that doesn't live in the dependency chain of the project you're currently working on. Nice!

Command+3 (Ctrl+3 on Windows) is your friend. It brings up a quick search of all menu items, keyboard commands, and shortcuts. This is one Eclipse feature I really wish Visual Studio had--I use it all the time and it makes learning the IDE far easier. Unless, of course, you don't know what the command you want is named....

The command I want most but couldn't figure out the name for: Backward History. It's the rough equivalent of Ctrl+Tab in Visual Studio. There's also a Forward History.

Eclipse builds all the time by default. You can turn this off in the Project menu, at which point Ctrl+B does what F7 does in Visual Studio.

Thanks to Fred's tips--especially the one about Command+3--I've been able to use Eclipse for a week or two now without wanting to chew off my own arm and use it to club people to death. So that's an improvement. I won't say I love Eclipse--I doubt I ever will--but I'm coming to terms with it. If I find any more useful tips I'll post them here.

Ianhttp://firstname.lastname@example.com:blogger.com,1999:blog-4366277884301889887.post-52543411028597042922011-05-18T22:03:00.000-07:002011-12-01T15:06:18.885-08:00NDK debugging without root accessRecently I made a comment to the effect that while ndk-gdb enables debugging on unrooted devices, Nvidia's Eclipse plugin and WinGDB's Visual Studio plugin don't. This means that if you want easy, IDE-based device debugging today, you need to start by running "adb root". Maybe that doesn't seem like a problem if you've already rooted your phone or if most of your debugging is done on an emulator. But if you're trying to develop on your personal phone, and it's a subsidized phone from a carrier that locks out root access, and you're trying to debug something the emulator doesn't support (cough, OpenGL 2, cough) this is kind of a big deal. Even if you've got a rooted device, why run as root if you don't have to?

This isn't meant as a criticism of either NVidia or the WinGDB folks. WinGDB has explicitly said they're only supporting emulators right now, and NVidia is targeting its own devkits that have AFAIK always shipped rooted. I highly doubt that they tried and failed to debug without root, I just don't think that they've had any real reason to try. But I was surprised to see just how small of a change needs to be made in order to enable debugging on unrooted devices.

The short answer to the question "how can I debug a process if I'm not root?" is simple: the debugger needs to run under the same account as the process it's debugging, and it can't do things (e.g. create sockets) which might be forbidden to that account. The long answer is more involved, because running under the same account isn't quite as simple as it sounds. To understand why this is tricky, let's first revisit how accounts and privileges work on Android.

When it comes to restricting privilege, desktop OSes have nothing on Android. Windows, OSX, and Linux all have the concept of root and non-root accounts, but they apply these concepts mostly to users (although both consumer OSes have followed *nix's lead in allowing sudo-style temporary privilege escalation, which while sometimes annoying, at least prevents everyone from running as root all the time). In general, every process the user runs has access to the same files and settings as any other process, give or take. Which means that "OpenOffice.exe" and "MalwareRiddenToolbarInstalledWithSomePornMyRoommateDownloaded.exe" have approximately equal ability to read, write and delete your stuff.

Android takes a different tack, one that's more common in mobile systems: it creates a different account for each app. This has two immediate advantages. First, every app gets its own "home directory" that other apps can't access, so it's harder for programs to screw with each other. Second, it makes it easy for the system to customize a set of privileges for each application. Some apps need to access the Internet, write to your contacts list, and send SMS texts; others don't.

But this compartmentalized security model makes life hard for gdbserver. While the underlying Linux permission model for debugging is pretty reasonable--as a normal user, you're allowed to debug any app that's running under the same account--that model assumes that accounts are tied to users or roles, not individual apps. What works on the desktop fails on Android because by default the app and the debugger will run under separate identities.

As an example, here's me trying to run the command line that WinGDB issued for my most recent debugging session. I'm running it against an unrooted Xperia Play. (I extracted the command line using ProcMon .)

>adb shell /data/data/com.example.testwingdb/lib/gdbserver :1001 --attach 1221
Cannot attach to process 1221: Operation not permitted (1)

No dice. The process I want to debug is running under the identity that's been assigned to com.example.testwingdb. But gdbserver is running under a different account--in this case, the default shell identity.

So what to do? Well, it turns out that there is a simple way out of this mess. Android ships with a utility called run-as. The run-as command takes a package name and a command line, then turns around and executes that command line under the security identity of the package you named. It's just like sudo, except run-as lets you specify which identity you want to run under while sudo always uses root. [Edited to add: Some Android device builds have issues with run-as. See my comment (comment #3 below this post).]

Here's me running the unix "id" command first without, then with "run-as". (For this example and the ones that follow, I'm using a package called com.example.testwingdb. If you're playing along at home, substitute your own package name.)

>adb shell id
uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1009(mount),1011(adb),1015(sdcard_rw),3001(net_bt_admin),3002(net_bt),3003(inet)

>adb shell run-as com.example.testwingdb id
uid=10117(app_117) gid=10117(app_117) groups=1003(graphics),1004(input),1007(log
),1009(mount),1011(adb),1015(sdcard_rw),3001(net_bt_admin),3002(net_bt),3003(inet)

So we use run-as and all is dandy, right? Not quite yet. The last part of the trick is that the executable we want to run with run-as, in this case gdbserver, needs to be in a place where our app uid has permission to execute. Sharp-eyed readers may have noted that my instance of gdbserver lives in /data/data/com.example.testwingdb/lib. Fortunately for the lazier programmers among us, it's not there by accident. It got there because ndk-build automatically puts it there when it makes a debug build. It puts it there because that's where it needs to be if you want to run it under com.example.testwingdb's uid.

With this in mind, we can make a very small tweak to the command line:

>adb shell run-as com.example.testwingdb /data/data/com.example.testwingdb/lib/gdbserver :1001 --attach 1221
Attached; pid = 1221

Woohoo!! Gdbserver is launched and has successfully attached to my process. All is perfect.... well, until this happens:

Can't bind address: Permission denied.
Exiting

Here we see the second consequence of the Android security model: apps have fine grained permissions. In this case, my app never asked for Internet permissions, so it's unable to open a socket--and because gdbserver is running under my app's uid, it can't open sockets either.

There's two ways to solve this. We could just modify our app manifest to request Internet permission. But that would suck: we don't need that permission for anything else, so we'd be making a significant change to our app's capabilities just to make it debuggable. A better solution is to do what ndk-gdb does: create a named pipe that gdbserver can use instead of a socket. Communication over named pipes doesn't require special permission as long as the pipe itself is accessible to the app, and adb includes the "forward" command that magically turns a device-side named pipe into a host-side socket:

>adb forward tcp:5039 localfilesystem:/data/data/com.example.testwingdb/debug-pipe

To use the named pipe, we launch gdbserver like this:

>adb shell run-as com.example.testwingdb /data/da
ta/com.example.testwingdb/lib/gdbserver +debug-pipe --attach 1221
Attached; pid = 1221
Listening on sockaddr socket debug-socket

And BAM. We can now connect up our favorite gdb client to port 5039 on the host, and it will communicate with the device-side instance of gdbserver over the named pipe /data/data/com.example.testwingdb/debug-pipe.

As far as I can tell, that's all it takes to enable rootless debugging. Let's review:

Launch gdbserver under the uid of the process to be debugged, using run-as.

Tell gdbserver to use a named pipe instead of a socket to communicate with the host.

Use adb forward to forward the device-side named pipe to a host-side tcp socket.

Hope that helps!
Ianhttp://email@example.com:blogger.com,1999:blog-4366277884301889887.post-9844771156641773852011-05-16T22:46:00.000-07:002011-09-06T13:49:25.396-07:00Android talks from GDC......are now available online, mostly. And mostly in new improved form. We were able to get almost all of the talks accepted to Google I/O this year, and those sessions were taped. So check these out:

My talk, Bringing C and C++ Games to Android, which I got to late and with an incredibly hoarse voice. Aaargh. Dan Galpin was my co-presenter and he covered for me on the first couple of slides. Thanks Dan! This talk is a good intro to the NDK, and also contains an overview of common pitfalls that we've seen in more than one game.

Dan's other talk, Evading Pirates and Stopping Vampires, covers nifty license server tricks for protecting your IP. This is especially important for games that host additional content (as in, the stuff that didn't fit in your apk) on the web. Nonpaying customers can suck your bandwidth bill and kill your profits if you don't take some precautions, but the Android license server can help protect you from these vampires as well as from more traditional pirates.

Nico Weber's 3D Graphics on Android: Lessons Learned from Google Body. Nico ported Google Body to Android, and he pulls no punches when he talks about the issues he ran into. A must-see for anyone who's tackling serious OpenGL programming on the Android platform.

And the great Chris Pruett, no longer a Googler but still passionate about Android gaming, reprised his excellent presentation Building Aggressively Compatible Android Games. Check out Chris's new venture, Robot Invader. He's already got a better blog than mine, so go over there and read his stuff now.

Sorry to the audio fans out there--the Android audio team was busy writing code and couldn't come to I/O to present the OpenSL talk that they did at GDC. Bummer! We'll try and get Glenn and Jean-Michel out to another conference or Dev Day soon so we can get their talk on the Web.

Ianhttp://firstname.lastname@example.com:blogger.com,1999:blog-4366277884301889887.post-17463547046228996112011-05-16T22:09:00.000-07:002011-05-16T22:09:39.655-07:00Victory!I finally got the latest version of WinGDB For Android to really truly work. Best news: it's faster than the Eclipse debugger. A lot faster. So far it feels about as fast as the Xbox 360 debugger--not as fast as local, but very usable. So, about as good as you can expect from what is, after all, a remote debugger operating over a serial link.

Just a few small snags in what is, after all, still a beta product:

Your device has to be rooted. I think this is because nobody's quite figured out that you need to do some special things to run gdbserver as non-root. The ndk-gdb shell script does it right; WinGDB and the NVidia Eclipse plugin don't.

You have to run Visual Studio as administrator. I found this really surprising, since it's been possible for years to build a VS plugin that didn't require admin privileges to run. Even a debugger replacement.

I couldn't get WinGDB's "Deploy" option to work. Even when it said it worked, it turned out to have not in fact succeeded. Their website says this is due to an adb bug. I'm skeptical; I was able to "ant install" from my project directory quite reliably. On the other hand, I was just using ant to install to the default device, and they're trying to make sure the deployment goes to a specific device (the one you said you wanted to debug on), so maybe they're hitting an edge case that makes adb fall over.

Dependency checking seems to be nonexistent--doing anything seems to trigger a build of the world. And I mean anything, including pressing the "Debug" toolbar button. This is pretty annoying even when "the world" is a sample project with one source file in it. On an actual application, it will be crippling. If they fix nothing else, this has to be remedied.

Intellisense is broken. This sort of doesn't surprise me; the VS plugin mechanism makes it kind of hard to replace the native debugger and build system without replacing absolutely fucking everything. I was kind of hoping Visual Assist might step in and lend a hand, but no dice. From Visual Studio's point of view, you're not in C++ anymore, you're in some alien project that it has no hope of understanding. The good news is that the WinGDB folks know this and claim to have a fix in the works. I'll be really interested to see what they come up with.

And a smattering of small UI bugs that you'd expect from a beta build.

All in all, not bad. The inability to do a minimal build has me worried, but I'm going to do a little poking around and see if it's something I'm doing wrong. If I can get it fixed, this might turn into my main debugging tool.
Ianhttp://email@example.com:blogger.com,1999:blog-4366277884301889887.post-37222785293787917902011-04-27T12:04:00.000-07:002011-04-27T12:04:34.619-07:00Big life changes!

It's been a crazy few weeks for me. First and most importantly, our daughter Amanda Evelyn (Chinese name: Yilan) Ni-Lewis was born on April 9! Mother and baby are doing fine, although at 8lbs 8oz little Amanda was quite a burden on my not-so-large wife.

Second, on the day before Amanda was born, I officially transferred to Android Developer Relations. I'd started out in Chrome and spent a few months covering the gap left by Mark DeLoura's departure as Game Developer Advocate lead, but I've been wanting to get back into a more technical and product-focused role. When my friend Chris Pruett quit Android to go chase his dreams, an opportunity opened up and I took it. So I'll be working much more closely with Android game developers now. I'm still helping to coordinate Google-wide game developer relations activities, but that'll be more of a 20% project for me from now on.

I'm also taking the plunge and trying to learn to love Eclipse. I'm not sure how that's going to go. I'll keep you posted. :-)Ianhttp://email@example.com:blogger.com,1999:blog-4366277884301889887.post-59365887340615031592011-03-28T13:34:00.000-07:002011-05-16T23:46:35.557-07:00GDC slides, how do they work?[update: (versions of) (most of) these talks are now online!]

tomaswoj writes, "I would love to see the presentation you gave on NDK/C++ in Android on GDC2011. You've mentioned that it will be up for d/l at some point of time. GDC already shares lots of this year presentations in their 'free' section, but yours is not among them. Does it mean, it will be in the pay area only? Or just overlooked? "

So, here's the deal. Back in a more innocent time of my life (late February), I was under the impression that it would be fairly easy to get slides posted online. I thought it would be about as easy as getting them OK'd for GDC in the first place--a little tedious, but not that hard. Hah. I was wrong.

First and foremost, game developer relations deals with multiple product teams, each of which has their own PR org. We have to make sure that each team is ok with what we're saying about their product. And in the case of posting slides online, we need to be sure that nothing can be taken out of context, because we don't have the luxury of explaining them or doing Q&A. So Chrome, App Engine, YouTube, and Android all need to be cool with not just the slides, but with all of the many uses and misuses they might suffer as they get passed around on the web.

Most of the product teams have signed off or requested small changes. But Android is different, and this is why the answer to @tomaswoj is not going to make him (or me) happy. See, Android is not a Google product in the way that Chrome or Gmail is a Google product. Android is a product of the Open Handset Alliance, which is an industry consortium involving many, many companies--carriers, hardware manufacturers, and so on. It's true that Google has an important role in the Android ecosystem, but it's not a lone wolf. The challenges of balancing the needs of all of the OHA's members make Android PR extra careful.

All of which boils down to one sad fact: Android's policy, which I learned after the fact, is to release slides only if they are accompanied by video. And we did not have budget for video at Moscone. (It's a union shop--we couldn't just handycam it ourselves.)

So, what's going to happen to those slides? Well, there is one possibility that I'm exploring. The developer relations team does have a budget for video production at Google I/O, which is happening in May. It turns out that many of the presentations my team is giving at I/O are very similar to the ones we gave at GDC. (One might even say we were recycling the material. I would respond, waste not, want not.) So there's a reasonably good chance that we can post the material online after I/O.

Does this suck? Yes. I learned a sad lesson this month. I'm very sorry that others--our excellent speakers and the developers who need this material--have to suffer for my sins. We'll do what we can to make the material available in some way, as soon as we can. But I can't make any promises about the NDK talk or any other Android material.Ianhttp://email@example.com:blogger.com,1999:blog-4366277884301889887.post-62984499650897489752011-03-24T10:18:00.000-07:002011-03-24T10:20:24.286-07:00Handedness! Argh!This week I started hacking on Unity, because all the cool kids are doing it. I wanted to see what all the fuss was about. So far I'm pretty impressed. I like the component-oriented architecture, which is something I've been lazily experimenting with since I left Offset Software eighteen months ago. One of the frustrating things about Offset (and many other engines) is the monolithic entity model: every entity has physics, audio, etc., whether it's needed or not. In Unity every entity starts out empty and you add components as necessary. I don't know much about the underlying code in Unity, so I don't know how far down the component-oriented thing goes, but it seems pretty promising so far.

I also got a copy of Maya, because I was sick of trying to learn Blender and we ended up with an extra copy at work. W00t! So now I can kick it like a real artist. (If only I were a real artist. So far I've been able to create a bad copy of the ship from Elite, and that's about it.) And best of all, Unity imports Maya files directly. No exporter FTW!!!.....

...and that's where the problems began. Because Maya is all about right-handed coordinates, and Unity is resolutely left-handed. And neither product seems to offer any feature that would fix this. Maya has a left-handed tangent space option, but nothing for actual world space. I can flip my models 180° in Maya (this works because they're symmetrical around Z), but that doesn't actually change the vertices in Unity--it just adds a 180° rotation to the model's transform. Which is useless, because that's the world transform--there's no "import space to model space" node that I can find. Useful things like the Unity follow-cam use that transform to figure out which way the model is pointed. This led to hilarity as I tried multiple ways of rotating the model in Maya, only to find that no matter how I rotated it, and no matter what orientation the model appeared to have in my Unity scene, the follow-cam always floated around to the exact same spot right in front of my little spaceship. (In case you're new to this, let me emphasize that the follow-cam is supposed to always be in back of what it's following.)

I guess the right thing to do is probably to parent the model under some other game object, and let the parent-to-child transform take care of the handedness switch. (I still need to figure out how to load a Unity transform with a matrix that inverts Z, because doing a 180 around Y isn't going to cut it forever.) But it still chafes me that neither Maya nor Unity has a simple way to invert Z. This seems like the kind of problem that would crop up fairly frequently.

Maybe someone reading this knows how to fix the handedness mismatch between Maya and Unity in a clean way?Ianhttp://email@example.com:blogger.com,1999:blog-4366277884301889887.post-73118849241784334402011-03-19T19:02:00.000-07:002011-03-19T19:02:24.566-07:00So close but yet so far...So WinGDB has a beta up of their "mobile edition," which is light years beyond the hacktastic preview I wrote about a couple of months ago. I installed it today and wow. This is what Android hacking on VS was meant to be. You can create projects via the normal new project dialog, you can start debugging with the normal play button, and all of the random settings and junk that we had to deal with before are gone.

What's really scary-cool is that they're actually working within the NDK make system. The project file is not a .vcproj or an MSBuild file, it is Android.mk. You add a file to the project via Visual Studio, and that's where it lands. That means they have completely rewritten the storage part of the Visual Studio project system, which is kind of a big deal. I'm not sure if I agree 100% with the design (I'm actually kind of a fan of MSBuild, at least for Visual Studio stuff)*, but I have to respect that kind of work.

Only problem is, right now it doesn't work! Not on my computer, anyway. It does what looks like a full and successful build, but then tells me that the build failed and refuses to launch the debugger. I turned diagnostics up to 11, but I can't find anything that even looks like a failure in my build log. Building from the command line via ndk-build works fine. But no luck getting Visual Studio to act like all is well. I'll ping the WinGDB guys, of course. I'd be interested to know if anyone reading this can get this to work. I must be doing something wrong, but I've tried this with both the NDK samples and a scratch project, and I'm not having any luck.

Well, it's probably for the best. I'd promised myself this would be the weekend that I finally learned how to use Unity. So I'll get onto that. Leave a comment if you get the WinGDB beta working better than I did...Ianhttp://firstname.lastname@example.com:blogger.com,1999:blog-4366277884301889887.post-11830835701189433432011-03-19T18:22:00.000-07:002011-03-19T18:22:26.852-07:00Weekend Blogging: a recipe hackThree weeks ago I made a soup with Lagunitas GnarlyWine that was so astonishingly not vile that I wanted to share the recipe. Of course, I promptly forgot it--probably because the GnarlyWine was accompanied by a half liter of Hop Stoopid, which did not go into the soup. (Neither did half the GnarlyWine, come to think of it.) So I have no recipe to remember that weekend by. In fact, I have very little memory of that weekend in general, except for a recollection of Hop Stoopid being one of the most awesome beers I've ever had.

So this weekend I'm writing down what I remember of my most recent experiment. Alcohol was not involved--quite the opposite, in fact. I wanted to make Beef Burgundy in our new automatic pressure cooker. But, the wife is pregnant, and pouring an entire bottle of wine into her beef stew sounded like a bad idea. Even if most of the alcohol did cook out, she'd kill me--she's very, very careful of our baby's health.

So how to spice beef stew without wine? I stumbled upon what turned out to be an amazing mix: onion powder, balsamic vinegar, white truffle oil, and just a bit of cheap-ass Costco brown gravy mix. Oh, and some McCormick garlic Season-All, probably because I use so much of it that nothing tastes right without it. Here's the recipe I ended up with (all measurements are approximate):

16 oz ribeye steak, cubed
1 lb bag frozen peas & carrots
3 red potatos, also cubed
1 tbsp 10 year old balsamic vinegar
1 tbsp white truffle oil
1/2 tbsp onion powder
1/2 tbsp brown gravy mix
1 tsp garlic Season-All
1 tsp basil
1 tsp oregano
1 tbsp extra-virgin olive oil

Combine in pressure cooker, pressure cook for 30 minutes (the auto cooker's "soup" setting) and stir vigorously to break up the potatoes a bit so they thicken the stew. Mwah!

The pressure cooker really is amazing. The meat was so tender. Well, ok, it was USDA choice ribeye, so no real surprise there. But everything was better than it had any right to be after half an hour of cooking. It tasted like it had been slow cooking all day. All the juices and flavors were mixed--even the potatoes were flavorful all the way through. I didn't even want the thing, it was my wife's purchase, but now I'm totally sold.

Oh man, you know what would go awesome with this? A bottle of burgundy. Good thing I'm not pregnant... :-)Ianhttp://email@example.com:blogger.com,1999:blog-4366277884301889887.post-22651883161353530132011-03-12T11:02:00.000-08:002011-03-12T11:02:37.060-08:00In case you're wondering...It's been a while since my last update, I know. I caught some kind of flu at GDC that's left me tired and weak. Didn't help that, due to missing our anniversary on Feb. 27, I'd promised my wife to spend Monday on whatever she wanted. That turned out to be moving lots of heavy furniture around to get ready for our baby and for her mom to come stay with us. So on top of the flu I threw my back out.

Anyway, I'm still sick and doing more than answering email is pretty much beyond me at this point. But I do have a beta of WinGDB 2 and I'll hopefully get a chance to try it out before it actually gets released. So stay tuned :-)Ianhttp://firstname.lastname@example.com:blogger.com,1999:blog-4366277884301889887.post-19946714785370337252011-03-02T10:24:00.000-08:002011-03-08T10:25:46.669-08:00Another Open LetterAn Open Letter to whomever stole my Motorola Xoom tablet at GDC.

Dear Sir or Madam:
You stole my stuff. You suck.

Unless, of course, you use that Motorola Xoom to create a fantastic app for the Android Market. In which case, good on you and I'm glad you're a little lightfingered.

:-)

IanIanhttp://email@example.com:blogger.com,1999:blog-4366277884301889887.post-71512313428760054452011-03-01T20:48:00.000-08:002011-03-01T21:01:59.715-08:00Letter to a Bike Thief
An open letter to whomever stole my bike from the rack at the Moscone Center last night.

Dear Sir or Madam,

First of all, ha ha ha ha ha ha ha. I hope you enjoy your new bike. Especially the way the chain falls off when you downshift. Or the way the right-hand shifter sticks and has to be yanked back with your thumb. Enjoy the slow leaks in both of the tires. And especially enjoy the way you'll have to pump up those leaky tires with two separate bike pumps, because one of the tires has a normal red-blooded American valve, and the other one has one of those elitist European things with the long stem and the little screw gadget on the end.

Second, let me just be the first to salute what I can only assume to be your giant, brass-cored, steel-belted, chrome-plated set of cojones. That bike was locked up right on Market Street in full view of thousands of convention-goers. Admittedly your average Game Developer Conference attendee isn't the most physically imposing specimen, but still. There's an awful lot of them, and they're going back and forth in that area all day and all night because they're diehard party animals. So bravo, sir or madam, you have got to be swinging a massive pair.

Lastly, I want you to understand just what this means to my life. You didn't just steal a reasonably nice but sensibly priced road bike from me. You took away my mode of transportation. That means I have to buy another bike. And that's five hundred to a thousand dollars that could have gone to pay for so many other things.

For example, will I now be able to convince my wife to let me buy a new Xbox 360, the new black one with that fancy new camera controller thingy, even though I already have like five 360s sitting in the garage waiting to get their red rings of death fixed? No. And I was this close to talking her into it, too, man. But now that money is bike money. So I will not be playing Dance Central using my body as a controller this month. There will be no evacuating the dance floor for me. I'm going to have to get by with a regular controller and a stupid white Xbox just like I did last month.

And it's not just the Xbox, either. A bike costs a lot of money. Will I be buying a stack of new games or a bunch of e-books this month? No, that's bike money now. Can I get my 1995 Acura Integra detailed and waxed 'til it shines like the top of the Chrysler building, like I was planning? Gonna have to wait until the bike's paid off. Will I be sipping Champagne and dining on the finest cuisine San Francisco has to offer? Well, yes, because I plan to expense that. But those new shoes that Baby needs? Bike.

Okay, thinking about it, my life is pretty good. You probably need the bike more than I do. After all, I still do have one Xbox that hasn't red-ringed yet, and I've always got my 1995 Acura Integra (last model year before they nerfed the engine control computer!) to fall back on.

So enjoy the bike. You're the one that has to live with being a lousy thief.
Ianhttp://email@example.com:blogger.com,1999:blog-4366277884301889887.post-27815313698621566352011-03-01T20:44:00.000-08:002011-03-01T20:44:37.798-08:00GDC: Coming up for airAfter 2.5 days of GDC I'm finally coming up for air a bit. It's going really well. Our Google sessions played to a nearly full house, and we've been turning people away from the Android sessions all day long.

I spoke last night at the Social and Online summit about lessons we learned from Google TV, and again today at the Android dev day on the Android NDK. What do those topics have to do with each other? Nothing. What do I know about either of them? Well... let's just say I had a lot of studying to do.

I actually co-presented both talks. The main speaker for the Google TV talk was Andrés Ferraté, who has given me two gifts in life: one, a much better understanding of Google TV, and two, the knowledge of how to type an 'é' on the Mac. (Everyone who knows Andrés learns how to type é at some point. It's kind of a thing with him.) Andrés put together the main slides and I stepped in to play the role of "guy who knows console gaming" to talk about how Google TV is not a console. It was a fun talk to give, very fluffy but entertaining. For me, at least.

The talk today was much more technical. I played the role of "guy who will explain the basics of the NDK," which was right in line with the work I've done so far. I talked about the ins and outs of getting started and using the NDK on Windows, and introduced things that I've been talking about on this blog, like WinGDB and vs-android. Then Dan stepped up to the plate and laid down his unique brand of magic, otherwise known as "knowing pretty much everything there is to know about NDK programming." Go teamwork!

So dev days are over, and I'm relieved. There were some gaffes but overall I'm pleased. Thanks much to everyone who attended!
Ianhttp://email@example.com:blogger.com,1999:blog-4366277884301889887.post-63540808250886875562011-02-21T18:08:00.000-08:002011-02-21T18:08:35.072-08:00One week to go...I learned something today: putting on a show, even just a little corner of a show like Google Developer Days at GDC, is really hard. Combine that with the fact that I somehow volunteered to give two talks, and write a bunch of content for our new website, and I'm just about worn out.

I've definitely learned my lesson about the talks: next time I'll either volunteer to organize things or to develop original material, but not both. It's not that either one is difficult, or that I didn't have time for both; it's that the two activities are very different and trying to juggle both was mentally exhausting. Not to mention that it put me in the position of being both boss and worker--I was developing my own material (and blowing deadlines, natch) as I was also trying to crack the whip on other developers and try and get them to meet the same deadlines I was having trouble with. I've gotten better at the management gig over the last twenty years, but it's still really hard to push people to do something I'd have a hard time doing myself.

But my slides are done (well, almost--a little extra polish never hurts), and rehearsals are almost over, and in a week we're going to put on a great show. And then I am going to go hide in a corner and write code for a couple of months. :-)Ianhttp://email@example.com:blogger.com,1999:blog-4366277884301889887.post-58684450429468586642011-02-13T18:14:00.000-08:002011-02-13T18:14:18.676-08:00GDCIf you've been following my twitter feed--or any of my coworkers' feeds--you've probably heard that we launched a GDC microsite a few days ago. This was my first experience launching a site at Google, and overall it wasn't bad. We got Ryan Thomas, who designed the Google TV site, to do the layout for us. Ryan is actually working on something a lot bigger for us, which we haven't yet announced, but he agreed to take a little time out of his busy schedule and put this together for us.

If you haven't already, this would be a good time to check out google.com/gdc2011. Especially check out the speaker bios--it turns out we have more game developers working for Google than you might have thought! We'll probably be adding some latecomers, too, as some of the talks will have more than one speaker. For instance, Dave Springer is probably going to show up. Who's Dave Springer? Oh, he just founded a little company called Alias. You might have heard of it.

Hope to see you all at GDC. Come check out the Google developer days--I can promise you it will be well worth your time.Ianhttp://firstname.lastname@example.com:blogger.com,1999:blog-4366277884301889887.post-20429818744728422542011-01-26T20:14:00.000-08:002011-01-26T20:15:26.413-08:00In which I access a fileHola amigos! Sorry it's been so long since I rapped at ya, but shit's been going down, you know? Shit, in this case, being Google's GDC presentations--two dev days and a couple of sponsored sessions, twelve talks total. We finally have a schedule and with luck we might even be able to post it soon, woohoo!! Now if I could just get my slides done....

But anyway... I got a little more time to work on Android NDK programming last night. I was planning to play around with VBOs a bit, but I got a little sidetracked. See, I wanted to load up my shaders from a file, like a human being, not put them in constant strings like some damn dirty ape. And files are kind of weird on Android, because everything goes in the apk. Getting stuff into the apk is super easy--just toss it in the "assets" directory, easy as pie--but getting stuff out is another story.

OK, first I have to thank Jeebus that I'm using Gingerbread and NDKr5, because I don't actually need to play games in Java to get access to the apk. If you want to know how blessed you are to be living in 2011 instead of 2010, just check out the old instructions for apk access (h/t to Dan Galpin):

Use the asset manager code to get an AssetFileDescriptor:

 AssetFileDescriptor afd =

 context.getAssets().openFd("ToothyDroid.png");

Read the offset and length from the AssetFileDescriptor:

 long offset = afd.getStartOffset();

 long length = afd.getDeclaredLength();

 afd.close();

Get the APK file name:

 context.getApplicationInfo().sourceDir;

Open the APK file at the specified offset and read the specified length. [Code omitted from original, because... why is that, Dan? Because it's a pain to write? ;-)]

Yeah. Weird.

Anyway, with r5 things get a lot simpler, because there's now an AssetManager library that lets you use the asset manager directly. If you're using NativeActivity and the native app glue, you even get your application's asset manager passed down from Java for free as part of the application class. So you end up with code that looks a lot saner:

 AAsset* pAsset = AAssetManager_open(ctx->app->activity->assetManager, "readme.txt", AASSET_MODE_UNKNOWN);

 const int count = 80;
 char buf[count + 1] = {0};

 while (AAsset_read(pAsset, buf, count) > 0) {
 LOGI(buf);
 }
 AAsset_close(pAsset);

That's better, right? It at least feels something like a normal set of filesystem calls. Rock on!!

Of course, it isn't a set of normal filesystem calls... which immediately makes me look ahead to the time when I'm going to want to access other filesystems (the SD card, for instance), and probably want to do so without having to plumb two different sets of file APIs all through my code. And while I'm at it, I probably want to abstract whether I'm even using a filesystem, or whether my files are in memory, or compressed, or streamed, or packed together in one huge bundle. I guess what I'm saying is, I've written enough data access code in my life to know that I'm going to want an abstraction layer at some point.

And so I pull out my trusty stream implementation... and run smack dab into the NDK build system. Ah, but that is definitely a post for another day. And probably at least a slide or two in my GDC talk.

Ianhttp://email@example.com:blogger.com,1999:blog-4366277884301889887.post-40498694503783225362011-01-18T13:29:00.000-08:002011-01-18T13:29:23.125-08:00Interview with TechWeb

UBM Game Network newsletter did an interview with me as part of their pre-GDC coverage. You can read the interview here. This was the first interview I've done over email. I'm pretty pleased with how it turned out--a lot of what I wrote got cut, but I expected that, and what's left is pretty much my own words.

I'm really excited about what we've got planned for GDC this year. We'll be doing two full days of presentations on Monday and Tuesday, and we'll have a booth on the show floor.

I'm in charge of the presentation content, so I'm doing a lot of running around trying to get everyone to finish their slides on time. Of course people will be fixing things all the way up to the day of the show, but we have to at least pretend to have deadlines. :-) The content is shaping up pretty well. We've got some really in-depth technical talks on Android and Chrome both. Most of the really deep tech stuff is going to be presented by the engineers that actually implemented the systems we're talking about. Should be really good.

If you want to hear more about GDC, or about game development at Google in general, you might want to follow @ilewis_goog on Twitter. I generally don't post more than a couple of times a week.
Ianhttp://firstname.lastname@example.com


text:
Cara from Craft Dictator was gifted this old drawer from her mom. When it comes to gifts, this one wasn't the prettiest–but luckily, Cara had vision.
After coating the drawer in primer, Cara dug some pretty turquoise paint from out of her mom's paint stash. She painted the entire drawer turquoise. Next, she decoupaged a map of Texas onto the bottom of the drawer. "I decided to put this on my coffee table either with some books on it or some glassware maybe. It might also just house my TV changers for a while! Either way I love love love the way it turned out!" Cara says enthusiastically. It's a brand new life for a drawer that could have easily been sent to the curb.
Learn more about the drawer repurpose at Craft Dictator.

subset: commoncrawl


text:
Birgid Schlindwein's
Hypermedia Glossary Of Genetic Terms
Search Results
|see Disclaimer
|The term was proposed by Waldeyer (1888) for the individual threads within a cell nucleus (gk. chroma, colour; soma, body). The self-replicating genetic structures of cells containing the cellular DNA that bears in its nucleotide sequence the linear array of genes. In prokaryotes, chromosomal DNA is circular, and the entire genome is carried on one chromosome. Eukaryotic genomes consist of a number of chromosomes whose DNA is associated with different kinds of proteins.
|The term introduced by Brown (1833) for the more or less spherical structure which occures in cells and stains deeply with basic dyes. The cellular organelle in eukaryotes that contains the genetic material.
|A subunit of DNA or RNA consisting of a nitrogenous base (purine in adenine and guanine, pyrimidine in thymine, or cytosine for DNA and uracil cytosine for RNA), a phosphate molecule, and a sugar molecule (deoxyribose in DNA and ribose in RNA). Depending on the sugar the nucleotides are called deoxyribonucleotides or ribonucleotides. Thousands of nucleotides are linked to form a DNA or RNA molecule. See also base pair.
|The term coined by Johannsen (1909) for the fundamental physical and functional unit of heredity. The word gene was derived from De Vries' term pangen, itself a derivative of the word pangenesis which Darwin (1868) had coined. A gene is an ordered sequence of nucleotides located in a particular position (locus) on a particular chromosome that encodes a specific functional product (the gene product, i.e. a protein or RNA molecule). It includes regions involved in regulation of expression and regions that code for a specific functional product. See gene expression, allele.
|Cell or organism lacking a membrane-bound, structurally discrete nucleus and other subcellular compartments. Bacteria are prokaryotes. Compare eukaryote. See chromosomes.
|Cell or organism with membrane-bound, structurally discrete nucleus and other well-developed subcellular compartments. Eukaryotes include all organisms except viruses, bacteria, and blue-green algae. Compare prokaryote. See chromosomes.
|A large molecule composed of one or more chains of amino acids in a specific order; the order is determined by the base sequence of nucleotides in the gene coding for the protein. Proteins are required for the structure, function, and regulation of the bodys cells, tissues, and organs, and each protein has unique functions. Examples are hormones, enzymes, and antibodies.
[New Search Form]


text:
- Table View
- List View
Guykuby Bob Raczka
The wind and I play tug-of-war with my new kite. The wind is winning. When you're a guy, nature is one big playground-no matter what the season. There are puddles to splash in the spring, pine trees to climb in the summer, maple seeds to catch in the fall, and icicles to swordfight with in the winter. Nature also has a way of making a guy appreciate important stuff-like how many rocks it takes to dam up a stream, or how much snow equals a day off from school. So what kind of poetry best captures these special moments, at a length that lets guys get right back to tree-climbing and kite-flying? Why, guyku, of course!
Here's Looking at Me: How Artists See Themselvesby Bob Raczka
This book introduces self portraits of painters and photographers painted in a variety of styles.
The Vermeer Interviews: Conversations with Seven Works of Artby Bob Raczka
In this innovative look at seven paintings by Jan Vermeer, author Bob Raczka takes on the role of interviewer and the people in the paintings become his willing subjects.
Select your format based upon: 1) how you want to read your book, and 2) compatibility with your reading tool. To learn more about using Bookshare with your device, visit the Help Center.
Here is an overview of the specialized formats that Bookshare offers its members with links that go to the Help Center for more information.
- Bookshare Web Reader - a customized reading tool for Bookshare members offering all the features of DAISY with a single click of the "Read Now" link.
- DAISY (Digital Accessible Information System) - a digital book file format. DAISY books from Bookshare are DAISY 3.0 text files that work with just about every type of access technology that reads text. Books that contain images will have the download option of 'DAISY Text with Images'.
- BRF (Braille Refreshable Format) - digital Braille for use with refreshable Braille devices and Braille embossers.
- MP3 (Mpeg audio layer 3) - Provides audio only with no text. These books are created with a text-to-speech engine and spoken by Kendra, a high quality synthetic voice from Ivona. Any device that supports MP3 playback is compatible.
- DAISY Audio - Similar to the Daisy 3.0 option above; however, this option uses MP3 files created with our text-to-speech engine that utilizes Ivonas Kendra voice. This format will work with Daisy Audio compatible players such as Victor Reader Stream and Read2Go.


text:
A nice group run
By tdw on Oct 13, 2005
I was a couple of minutes (only) late arriving at the club, but there was no-one waiting outside when I'd parked the car, and although I saw someone jogging up the road, I must have missed them. Probably not surprising really as it was raining hard, and only nutters go out for a run when it's like that! I had a quick jog up the road to see if I could see anyone disappearing into the distance, but alas no. So, feeling suitably miffed with myself for being late, I jogged back to the sports club with the intent of getting back in the car and going home.
However, when I got back to the club, there was a group of runners just about to set off. It turned out that they were a beginners running class from the gym at the sports club, and when I explained my predicament, they invited me along. Well, I was out and dressed for a wet run, so why not, I thought.
This was the first time I'd run with a group of people (outside of a race, which is different anyway), and I first ran with the ladies at the back and had a chat with them. Then I caught up the group leader from the gym who was a really nice guy. He said his intent was to get everyone in the group into at least one 10k before Christmas, and having run along with them, I'd say they were all more than capable of putting in a good showing in a 10k. I ran with other pairs along the route, gradually catching up the leaders, and in the end tagged on with a woman running alone who was setting a very good pace for a so-called beginner. We ran together for the last couple of miles and the pace gradually increased during that time, so that we overtook one of the two chaps at the front and weren't far behind the other one when we finished. She thanked me afterwards for setting her a tougher pace (I didn't like to shatter her illusion by telling her that I'd just been running along at her pace .
I have to say that I really enjoyed the whole run. It was good to run at different paces and good to chat with people instead of being left to converse with myself in my head.
So, next Wednesday, I'll try to get to the sports club a little earlier to see if I can catch the guys from the running club. Secretly, though, I won't be too disappointed if I miss them and have to run with the "beginners" group again


text:
Double click to close
Get Game ID or Title
Enter gameid
Get game title
Search: Enter game title
Get game title and ID
Get User ID or Username
Enter userid
Get username
Enter username
Get userid
Visit the
Old Games News
Project for daily Retrogames Entertainment.
Download Operation Stealth
Operation Stealth
Game Review
Stealth, of course, was THE buzzword of 1990 after various shenanigans in the Gulf, so it was no surprise that this tie-in of dubious parentage was originally released as a "James Bond: The Stealth Affair". By the time it crossed the pond to the UK, it had been discreetly rebranded as simply Operation Stealth, with the agent being renamed (ahem) "John Glames". A somewhat cack-handed approach had been taken to the conversion however, which led to some oddball quirks such as the CIA giving orders to MI6 agents. And the agents taking them. Where was that sort of collaboration when we needed it during the Profumo affair, eh? It's never quite clear why this change was made or indeed how publishers US Gold even got their paws on the license in the first place.
Operation Stealth was your average point-and-click adventure, very much in the LucasArts vein, but with (if the truth be known) damned annoying arcade sequences built in. One of these was a top-down view of a maze which you had to negotiate before your oxygen ran out. Remember Hungry Horace on the ZX Spectrum?
The plot was the usual mish-mash of derring-do in South America, trying to recover - you guessed it - a stolen Stealth bomber; kind of like Firefox, but with sunburn. Graphics were sub-par even for the time, betraying its roots as a port from the Commodore Amiga. The Expanded Amiga version, incidentally, had speech synthesis which grated out every single line and had an irritating habit of crashing should you be fool enough to move the mouse whilst it was chirruping away. Many a seasoned user wisely removed the memory expansion cartridge to avoid having to reboot every two minutes. This "feature" was sagaciously removed from the PC version.
Operation Stealth wasn't a bad game. Sure, the plotline was utter dross and you never quite felt engaged with the character that you were playing, but the puzzles were well thought-out and there were some novel twists in the story arc. Sadly though, the arcade sequences broke up the flow of the game at vital moments, and could provide an impassable barrier for those who were lacking the requisite joystick skills (or, come to that, joystick – this was 1990, remember). But the two-man team that were Delphine Software were obviously trying something a bit fresh and new and it's perhaps to their credit that later games successfully melded the two spheres together. Okay, the recent reinvention of Bond and the mothballing of the Stealth programme make this look even more dated, but Operation Stealth is still an enjoyable romp down memory lane.
Written by:
C:DOSian votes:
Poor, 3 votes
Mods votes:
Game Details
Created by:
US Gold
Release year:
Point & Click
More Cool Gamesites
Copyright © 2007. CDOSAbandonware.com


text:
Rep. Paul Ryan believes that the immigration system in the U.S. is "broken," and this weekend added that there is "doubt" about whether or not Congress will be able to pass a bill on immigration reform.
From Ryan's official House webpage on the matter, he states that the system is "broken" and adds that "the evidence is overwhelming." He states that the immigration system should be more accountable, efficient, and effective. Also, he cites two facts on the matter:
"First, 11 million undocumented immigrants are living in the United States. Because they lack legal status, they are outside the scope of the law. We don't know who they are or in what activities they are involved. Second, we encourage people to break the law and punish those who follow it. Immigrants who attempt to come to this country by legal means find themselves wrapped up in endless paperwork and bureaucracy. The current backlog for family-sponsored visas is so vast that it could take up to 11.5 years for the visa to be processed. As of November 2012, 4.3 million persons stood in the family-based visa queue."
And in an interview which aired Sunday on ABC's This Week, asked if there would actually be a bill for President Barack Obama to sign on the immigration issue, according to a transcript provided by ABC/ThisWeek, Ryan stated:
"I really don't know the answer to that question. That's clearly in doubt,"
He further told ABC anchor, George Stephanopoulos, that the thing which the Republican party did agree upon was that "... we don't trust the President to enforce the law."
But the Congressman, who was a Vice Presidential candidate in 2012, also believes and states clearly on his web page that reforming the immigration system "... will help America." Ryan writes:
"Immigrants contribute to our economy. They started one-fourth of all new businesses in 2011. And immigrant-owned small businesses employ 4.7 million people. In fact, first- or second-generation immigrants founded 40% of all Fortune 500 companies, including AT&T, Kraft, Google, Yahoo!, and eBay. As a result, the American Action Forum estimates that immigration reform will boost per capita income by $1,700 over ten years and reduce the federal deficit by $2.7 trillion."
Adds Ryan:
"Most countries use immigration to strengthen their economies—but we don't. In the U.S., only 7% of green cards went to work-based immigrants in 2010, but the vast majority of visas in other countries, like Canada and Australia, are directly aimed at work-based immigrants that can boost the economy. We give out visas based on people's family connections, not their talents or skills. We are missing out and falling behind."


text:
My latest (and possibly final) experiment with Wii remotes was to see whether it is possible to use two Wii remotes to maneuver my NXT. This project wasn't very technically challenging but it was a lot of fun trying to steer the NXT around obstacles. The two Wii remotes were used to control the left and right motors. The speed of the motors was controlled by the angle of the Wii. Pointing the Wii to the ceiling stopped the motor. As the Wii remote was tilted forward the speed increased until the remote was pointing straight ahead for maximum power. The A and B buttons controlled the motor direction.
Here's the video:


text:
La Salle's dedicated volunteers allow our school to offer students and their families engaging and memorable experiences. La Salle encourages parents to be actively involved in our community to enrich their experience as high school parents – and to benefit the community as a whole.
La Salle does not require mandatory volunteer hours. However, we ask parents to commit at least 20 volunteer hours each school year to their area of interest or expertise. Your gift of time and talent offsets thousands of dollars in expenses, while also providing your family the chance to experience our vibrant La Salle community.
Our programs and events are heavily dependent upon parent volunteers for success and we are grateful for every volunteer who chooses to partner with us. We welcome and encourage parents, past parents, alumni, grandparents, and friends of La Salle to volunteer at the school throughout the year.
Whether you are interested in chairing an event or helping on an occasional evening, your help is vital to continuing the legacy of community involvement at La Salle.
Please complete and submit this online volunteer sign up form and Lauren Craven '05, Advancement and Communications Associate, will be in touch with you soon to discuss your interests. Feel free to e-mail or call Lauren with any questions at 503.353.1444.
Currently, La Salle's main volunteer needs include:
For more information on these opportunities and to sign up, please e-mail firstname.lastname@example.com.
Called to Protect
Volunteers who will be in the presence of students, regardless of the amount of time, need to take annual Called to Protect training.
The first training requires the volunteer to attend a training session here at La Salle.
The current schedule for video training is:
No trainings are currently scheduled, If you need training for an upcoming volunteer activity please contact Mary Neil at firstname.lastname@example.com
If a volunteer has already completed the video training in a previous year, they will only need to complete an online module to become up-to-date for 2015-2016 year. Instructions for how to complete the module are downloadable here, or please contact Lauren or Mary for more information.
La Salle Catholic College Preparatory 11999 SE Fuller Road Milwaukie, OR 97222 Phone: 503.659.4155 Fax: 503.659.2535 contact us