talarubi: (Default)

My code—or rather my bugs, you could say—have apparently been trying to make an artistic statement.

No comment, except... I think they succeeded. o..o

talarubi: (Default)
Well, amongst smaller things, I requested (and got) a DS lite over Christmas. This should be no surprise to anybody, what with the supplied Pointy Thing and all the talk of touching... gah! Nintendo is so flaming gay now. AC is proof enough of that...

Which is probably exactly why I'm pleased, thus far.

(See, all you teen gamers? The lesson is, don't make fun of the artsy folks. If you do, their revenge will be a series of games focused on coffee shops, mortgage payments, gardening and interior design! See: The Sims, Sims 2, Second Life—okay it's not a majority but JUST YOU WAIT!)

Well seriously, the whole thing is better built than the $400+ PDA I got a few years ago, and it has smexier hardware too. I'm definitely gonna order a key and a media adapter and see what I can do.. The SC has 32MB (!) of RAM in it, and reads nice large SD cards, which should be more than enough to run things like an organizer, MP3 player or a port of Gaim. I don't think there's a compelling browser yet, but I don't really need to squint at LJ either...

Anyway!—
Mario Kart DS060217 402007
Animal Crossing WW4811-2421-4391

M'still figuring out how all this stuff works, and the wireless doesn't reach too well upstairs. But hey, someone might be interested?

Brrrr!

Dec. 1st, 2006 08:11 pm
talarubi: (the inscrutable starfish)
See also, visuals.

talarubi: (Default)
Last night I dreamt about little subworlds. There was one peculiar thing about them—they had more "there" there. What I mean is, if you did a quarter turn four times, as measured by a house wall for example, you wound up looking down a fifth hallway. Indeed, outside, the square buildings were five-sided.

Some guy had set them up and was showing people around. It was a subtle thing you tended not to notice for a minute, until you got lost. Also, one of them had a society living there that seemed under threat somehow—unsure whether it was meant to be real or fictional. (Insert lots of colors and details that probably made more sense at the time.)

My geography and chemistry teachers also made reappearances, doing catchy presentations ala Bill Nye on things I can't quite remember.

Ed note: Google says this is called hyperbolic space. And in fact it is very easy to get lost, because instead of having cubic amounts of "here and there" in an increasing radius, it's exponential! I feel sorry for the search teams, don't you?

Unfortunately I knew about that before my dream did. But I love the notion of quaint old houses and school buses and green fields pulling these tricks.
talarubi: (Default)
template<> struct promote<byte, unsigned shirt> { ... }
Hmm, might be enough coding for today. You know—first it's shirts, next thing it'll be volatile unsigned dryer lint. Then I'll be casting off box<short>s and long johns; and destructing Tokyo().

A purely virtual notion I'm sure, but you just can't be too careful...
talarubi: (mooooose!)
I wish I could write in two or three languages at once. Witness the following hypothetical example which might be used to disassemble machine code:
(decoderGroup new: `x86ArithmeticRegOps
    memberWhen:   `($code[0]  ~ @00??????
                 && $code[0] !~ @00????11)
    memberIndex:  `($code[0] takeBits: %00111000)
    members:      [ADD OR ADC SBB AND SUB XOR CMP]
    details:      [
        `(if `($code[0] ~ @???????1)
            ($dataSize = [32 16] choose:
                (bits16 in $cpuMode
                    ^^ toggleSize in $prefixes))
            ($dataSize = 8)
            )
        `($args = ($code[0] takeBits: %00000110)
            selectFrom: [
                (ModRMArgs bytes: code[1..] dest: regOrMem  src: reg)
                (ModRMArgs bytes: code[1..] dest: reg       src: regOrMem)
                (ImmedArgs bytes: code[1..] dest:
                    ([8:regAL 16:regAX 32:regEAX]
                        choose: $dataSize))
            ])
    ])


Compared with typical Pascal )

This sort of want happens to me a lot. Can you count how many languages I've plagiarised? How about the number of features missing from C++ or Delphi?

Myself, I see a little Smalltalk, Lisp, C++, even Perl and (oh gods) INTERCAL. There are literal lists, tri-valued booleans, hashes, class fields, and closures with named parameters.

I know people are going to tell me, 'learn LISP.' And I would agree, but there needs to be an infix expression syntax for numerical work. Haskell is interesting that way, as it sort of has both.

The lack of closures alone pains me so much, I can't imagine why anyone would leave them out! I love them in JavaScript. JS also has some great LISPy structured literals. These really should be a standard language feature--literal code, structures, and arrays, just like literal numbers or strings.

I don't know there's any language that does what I want. That's the thing... they all have different strengths. It would be great to be able to use the right syntax/structure for the right problem.

Hurrrf. Guess I'll be expecting that right around the time programmers stop treating language and technique as religion...
talarubi: (colorful pixelly)

I thought I'd try the Visual .NET Forms stuff in MSVC++ 2005. I hoped I could get a decent GUI up and keep the rest of my code as clean, platform-independent C++.

Maybe I'm just stupid, but this is the simplest way I could find to get a std::wstring path out of an explorer icon dragged atop the form:

System::Void MainWin_DragDrop(
    System::Object^ sender,
    System::Windows::Forms::DragEventArgs^ e
) {
    array<String^>^ dropList =
        dynamic_cast<array<String^>^>(
            e->Data->GetData( DataFormats::FileDrop ));
    
    String^         filePathCLR = dropList[0];
    std::wstring    filePathSTL;
    	 
    // "Obvious" method
    //for each( wchar_t c in filePathCLR )
    //	filePathSTL.push_back(c);
    
    // Suggested method (MSVC documentation... srsly)
    using namespace Runtime::InteropServices;
    const wchar_t* filePathRaw = (wchar_t*)(
        (Marshal::StringToHGlobalUni( filePathCLR )).ToPointer()
    );
    filePathSTL = filePathRaw;
    Marshal::FreeHGlobal(IntPtr( (void*)filePathRaw ));
    
    m_MyObj = new SomeDocumentObject(filePathSTL);
    // ...
}

There are several interesting things to be seen here. I'm not sure what to think of them.

For one thing, this isn't even C++! They've added a whole chunk of C# as completely new syntax. Seen here are the ^ which is their garbage-collected heap pointer, array (which is a keyword and derives from System::Array), and a few bits of their class library. Also notice the for each, where each and in are context-sensitive (!!) as keywords.

Oh, and don't even get me started on the freaking casts.

This syntax is completely required. The form designer generates it, and their library depends on the special references. That's because if you compile in "safe" mode, hoping to run under someone's tight security policy (and they encourage you to)... pointers aren't even allowed!

Naturally, this breaks just about every useful piece of C and C++ out there, including the all-important STL which sets C++ apart. While I understand the security motivation, I think this is misleading on MS's part, since at that point, it's not C++ anymore! It's just another dialect of C#, or maybe C# with templates. :/

I could simply compile in "pure" mode (effectively, insecure bytecode), and use the STL with the bureaucracy above, but it's still annoying. Mmmfeh.

talarubi: (Default)

So tonight, I was perusing some annoyingly table-y tech reference, and I wondered if it was feasible to print this out, four pages to a double-sided letter sheet, and bind it into bookish form. To my surprise, OpenOffice actually has some basic stuff documented, and I was able to get proper page headering and left/right page margins.

Time to print! I checked the Bookbinding Page Calculator, and got the following 2-up page orderings:

Front: 32,1,30,3,28,5,26,7,24,9,22,11,20,13,18,15,
1,33,1,35,1,37,1,39,1,41,54,43,52,45,50,47
Back: 2,31,4,29,6,27,8,25,10,23,12,21,14,19,16,17,
34,1,36,1,38,1,40,1,42,55,44,53,46,51,48,49

Feeling wary, I tried this first with the excellent PDFCreator. And fortunately so--can you guess what I got? Why, yes...!

1,3,5,7,9,11,13,15,18,20,22,24,26,28,30,32,33,35,37,39,41,43,45,47,50,52,54

So apparently some programmer thought he was ZOMG CLEVER!!@ and decided to "helpfully" union and sort the list. Except (nevermind, I think, that MS Word doesn't) that's not the purpose of this option at all! If anyone wanted foolproof consecutive numbers, they'd type a page range... yeah. Real smart.

*growls*

On another note, Windows Live Writer is still very sparse and beta, but actually kinda promising. For one thing, it works with LiveJournal (!) among others. I can take screenshots and paste them right in, and it uploads to Scrapbook without ever needing to save in between. They also try to grab your blog style and display it all WYSIWYG-like in the editor, although it doesn't completely work for me yet. Supposedly, it supports plugins.

Bah. I don't remember what else I wanted to say.

talarubi: (Default)

So DietPower, the food logger I use, decided as long as I'm sitting here, I could wait two minutes for the food log to open. It was already slow, but now it's firmly in the realm of code that doesn't scale.

C'mon, it's clearly a C job. No excuse. I know people who write faster apps in Perl!

Another irritating thing is it's missing an export option, so the only way to get the logs out involves manual inspection, and then writing the code. The latter's not so hard, but I always used to cringe at binary files. Maybe the braver people would drag out a hex editor.

Well, the first thing I reach for is EDIT.COM. That used to be because it's all I had that reliably saved binaries... too bad it doesn't do hex, right? But after awhile I noticed that an ascii view is really useful, quite possibly moreso.

For one, you get the best use of screen space, which reveals a lot of patterns. Intel code is very dense, with the occasional word-size data thrown in. C structs with small numbers (e.g. most of them) leave a lot of zero padding. Pointers and offsets can be seen growing throughout the file. Text, of course, is immediately readable.

Repeated data shows up especially well, since nearly every byte has a unique glyph. The exceptions, 0x00/0x20/0xff, are blank. Happily, this includes various representations of nil: space, the integers 0 and -1, floating-point zero--and unused numeric precision.

Other values show up too, for example values centered around 0x3f (?, @, A) which are sign/exponent bits for small positive floats. "  Ç┐" happens to be 0xbf800000, or -1.0. At left, it marks unspecified nutritional values. (Sloppy coding has introduced other negative values as well!)

If the file is just a series of structs, it shows up as angular striations, betraying the length and number of the records. Usually somewhere nearby is the count. If you know your hex and ascii (essentially base-16/256), you'll quickly find it, and now you can write a skeletal reader.

And then you can go try all the program's special cases, and make note of what it spits out. This is how I wrote my OpenCanvas reader. Maybe I can get DietPower's logs into a spreadsheet or something...

It does give me thoughts, though. Using EDIT works great, but it's still a pain to do the math. I wonder if there's a better editor out there. I think I should be able to select regions, say "this looks like a record", and have the thing pattern-matched down the whole file. Then I could say "these are float fields", and it would update everywhere.

I think I would have circular tooltips, where you hover over some data and it shows you all the different values it could be in each representation it knows, and then the most likely one. (0's or 1's on the left = small int, high bits near 0xbf, 0x3f = small float, compare to values in other instances of the record...) Then you'd right-drag through a pie menu to choose one of them.

There could even be a hex view, either through a lens tool, or using a color mapping on top of the numbers, to show patterns. Or you could space things out and display assembler inline with all the other data, using heuristics (statistics, file headers) or manual selection to identify the code.

Ideally it would come with different plugins for the known formats, and people could write their own. You could use it as a teaching tool for Operating systems 101, or to help debug things, or repair corrupt files.

Ohwell, I'm probably dreaming. But it would be helpful right now.

Level up!

Jul. 26th, 2006 06:44 pm
talarubi: (16-bit dracus)

If you can stand the quirks/don't need C++, Tiny C is amazing. Where GCC takes entire seconds per file on my machine, a Makefile running TCC spills output faster than the xterm can display. I only wish I was kidding!

TCC also comes in a library form that you can plug into your apps to compile C "scripts", can do optional bounds and pointer checking at runtime, and it even squeezes onto a floppy. Mind, it doesn't generate the best code, but then again, most isn't time-sensitive—and if your algorithms depend on a clever optimizer to be usable, they probably won't scale as it is... But I digress. In fact, there was a problem...

Talarubi@FRANCIS /c/Code/Magenta_bloo $ make run
tcc -g -o build/magenta.exe Fuschia.o Cyan.o White.o
  -L/Dev/gc6.6 -lkernel32 -luser32 -lgdi32 -lgc
build/magenta.exe
Segmentation fault

make: *** [run] error 5

Talarubi@FRANCIS /c/Code/Magenta $ gdb build/Magenta.exe
The debugging information in 
  `c:\Code\Magenta_bloo/build/Magenta.exe' is corrupted.
The file has a `.stabs' section, but no `.stabstr' section.
(gdb) break main
No symbol table is loaded.  Use the "file" command.
(gdb) . o O ( wtf? )
Further investigation revealed that compiling *.c to a binary worked, but compiling to *.o and linking these somehow mangled the debug symbols. And sure enough, an incriminating remark in tcc/src/tccelf.c:
/* load an object file and merge it with current files */
/* XXX: handle correctly stab (debug) info */
static int tcc_load_object_file(
  TCCState *s1, int fd, unsigned long file_offset)
{

"Correctly?" Erk!! Well they don't call it v0.9 for nothing, but it's not the sort of commentary one wants to see in a compiler!

But with the company of lazyweb, and some quick if mind-numbing research, things are looking up. Many hours later:

# Why not? Btw, no visible delay here
Talarubi@FRANCIS /Dev/tcc/src $ ../tcc -g tcc.c -lkernel32
Talarubi@FRANCIS /Dev/tcc/src $ ./tcc -g mathtest.o win32/lib/crt1.o
  -L./win32/lib -B./win32/lib
Talarubi@FRANCIS /Dev/tcc/src $ gdb mathtest.exe
(gdb) break main
Breakpoint 1 at 0x4011da:
  file c:/Code/Magenta_bloo/scraps/mathtest.c, line 94.
(gdb) list
85              unsigned overflow = xor & (x ^ modulo) & 0x80808080;
86              unsigned over_p = overflow & modulo;
87              over_p = over_p - (over_p >> 7);
88              unsigned over_np = overflow - (overflow >> 7);
89              return (modulo ^ overflow) & ~over_np | over_p;
90      }
91      
92      int main(int argc, char**argv)
93      {
94              if( argc < 4 )
(gdb)

And right now this is the most gratifying thing, being able to go and hack on the compiler, and even sort of comprehend what I'm doing. It's the wonderful feeling of a warm light shown on things that are black magic to most people...

Or maybe the feeling I might take over the world next Tuesday. That doesn't seem substantiated, though.

talarubi: (Default)
Some months ago I found a couple of brilliant pages (1, 2) on dealing with graphics data. By which I mean, four-component vectors packed into machine words. E.g. 0xAARRGGBB or struct { uint8_t r, g, b, a; }.

Applications like Photoshop or OC, are really just a slick interface over all these vectors. Since there are naturally quite a lot (e.g. tens of megabytes) of them, the authors have invested quite a lot of effort to speed up the math.

This is the lovely part. You don't have to know calculus, but you do need a twisted mind. For example, these two snippets add and subtract vectors, limiting the results to byte range. So annoying to do componentwise, but look!
sum = x + y;
low_bits = (x ^ y) & 0x010101;
carries = (sum - low_bits) & 0x01010100;
modulo = sum - carries;
clamp = carries - (carries >> 8);
result = modulo | clamp;


(modified, the original page did 16 bits)
diff = (x - y) + 0x01010100;
low_bits = (x ^ y) & 0x01010100;
borrows = (diff - low_bits) & 0x01010100;
modulo = diff - borrows;
clamp = borrows - (borrows >> 8);
result = modulo & clamp;
They compile to 12..14 intel instructions, adding in parallel and saving up to three expensive branches. Some manual assembler can even fix the carry problem (on the add) and do the full vector.

Here's a premultiplied alpha blend, resembling code from the linked page. They are computing destC = destC*(255-srcA)/255 + srcC. The first is approximate, and the second (in a not so obvious way) exact:
dest_ag = (dest & 0xff00ff00) >> 8;
dest_rb = dest & 0x00ff00ff;
alpha = 0x100 - (src >> 24);
dest_ag *= alpha;
dest_rb *= alpha;
dest_ag = dest_ag & 0xff00ff00;
dest_rb = (dest_rb >> 8) & 0x00ff00ff;
dest = dest_ag + dest_rb + src;
dest_ag = (dest & 0xff00ff00) >> 8;
dest_rb = dest & 0x00ff00ff;
alpha = 0xff - (src >> 24);
dest_ag = alpha * dest_ag + 0x00800080;
dest_rb = alpha * dest_rb + 0x00800080;
dest_ag = ((dest_ag >> 8) & 0x00ff00ff) + dest_ag;
dest_rb = ((dest_rb >> 8) & 0x00ff00ff) + dest_rb;
dest_ag = dest_ag & 0xff00ff00;
dest_rb = (dest_rb >> 8) & 0x00ff00ff;
dest = dest_ag + dest_rb + src;
This is based on the principle that 4 * 1020304 = 4 * (1000000 + 20000 + 300 + 4) = 4081216. The coefficient multiplies digits independently, preserving their place values. So while it looks complicated, it saves two multiplies and (in the second case) four (!) divides. The remaining logic is easily parallelized on its own, a cinch for modern compilers and CPUs.

Finally, here's one I noticed! It's just a componentwise product, treating the bytes as unit fractions:
dest_ag = (dest & 0xff00ff00) >> 8;
dest_rb = dest & 0x00ff00ff;
src_ag = (src & 0xff00ff00) >> 8;
src_rb = src & 0x00ff00ff;
dest_ag *= src_ag + 0x00010001;
dest_rb *= src_rb + 0x00010001;
dest_ag = (dest_ag >> 16 & 0xff000000) + (dest_ag & 0x0000ff00);
dest_rb = (dest_rb >> 24 & 0x00ff0000) + (dest_rb >> 8 & 0x000000ff);
dest = dest_ag + dest_rb;
This one's approximate, and needs a 32x32->64bit multiply (usually an inline library function or some assembler). Though 0*0 = 0, and 255*255 = 255, as intended. It's actually not so obvious why this works. The short story is that it's based on the expansion of (a + b)(x + y)...

(216*b + a) * (216*y + x) = 232*b*y + 216*(b*x + a*y) + a*x

explanation )
talarubi: (Default)
And then, whilst fixing waffles and coffee, I caught my brain remixing Final Fantasy and Billy Joel.

Huh, zilla? Anyone got a repro on that?
talarubi: (Default)
G'dammit... OpenCanvas' networking has taken to taunting me. Some 30-60 minutes in it'll just stop reading data from everyone else, so I'm effectively bumped out of the session, even though it's receiving it. Naturally this happens as soon as I really get into it.

So, I guess there's my motivation. I want a replacement, and I know roughly how I want it to work. I'll prolly try and think on the class design for a few days. I've been flailing way too much with microscopic C++ issues, so maybe the trip will be an opportunity to step back from the compiler, and work out something minimal and reasonable on paper. (I honestly don't think anything on the level of OC should be more than 3-5,000 lines of code.)

Wait, Tala, trip you say? What trip? Gah. Some relatives from the east coast are having a wedding up in Delaware, and we were all invited. It's a fifteen-hour drive. Yeeeesh. Since past the first day we will probably be bored beyond belief, we're doing a day of driving each way, and a day at the wedding. So I leave in 3-4 hours (x..x!) and get back on my birthday, e.g. Sunday. Double-yeeesh!

Honestly I'm tempted both ways... it would be a peaceful relaxing weekend at home with the parents gone, but I need to get out too. Total tradeoff. For better or worse, I haven't seen these people in years. That will be nicely awkward. Wheeee.

So, I'll see you all in a few days.
talarubi: (Default)
Something I've been wondering for awhile.

Discussions of the Halting Problem tend to talk about the paradox of a program that asks about itself, and then contradicts the answer. But that doesn't seem very interesting except as a proof! I'd really like, say, a program which is surprisingly difficult to pry apart and understand, or to make some desired modification without screwing it up.

For example, I hear some UNIX vendors sold systems with the source code, filtered so it was an obfuscated mess. You could compile and run it, but it would have been more effort to do your own dev work. Another one are viruses that decrypt themselves. This is still pretty primitive since either way, the machine language winds up as "plaintext" in memory anyway, and then you can just fire up your hardware debugger...

So is it possible to foil even that? Say you have the parse tree for some C++, is there some way to preserve what it does while seriously obscuring how it does it after compilation, and without requiring prior decryption? Preferably this would have to be many-to-few sort of thing, so you couldn't tell what a construct represented in the source, and semi-randomized. It should be a like a hash, where many bits of code depend on many other bits of code—dependencies, self-modification and side effects everywhere.

Now I don't suppose this would be all that useful, except for the really paranoid of the closed-source folks. More of a joke otherwise... heh! Maybe in that vein a C-to-Unlambda or Intercal or even Befunge compiler would work... XD

Other than that, I can't think of a good way to do it. Ahwell.
talarubi: (16-bit dracus)
Second Life, the sprawling hack that it is, has me thinking about multiuser systems lately, particularly how to do them better. One really cool thing would be to have peer-to-peer spaces. For a small group, that would be a huge improvement over the $200/mo Lindens want to maintain an island. Just connect to your local tracker, ala BT, and have all the room your slowest clients can cope with. It goes away when the last person leaves, or someone could save to disk. What could be simpler?

Well assuming you tackled the voluntary coherence issues, there is still no authority involved. It's peer-to-peer, so how could there be? Kinna confusing. Let me outline the situation... )

Now suppose our ever-enterprising Carol hacks apart her VM. The first thing she does is add an instruction to let her see all the objects and their data, particularly those in Sw. Then she uses that to inspect Bob's bank account, and is sorely disappointed because Bob is fresh out of funds. So she builds a camera situated in Sa, that lets her peek right into Alice and Bob's skybox. (Which, we suppose, is what he spent the money on—it is peppered with luxurious textures and neon poseballs. She makes a note to copy her favorites.)

I think it's very important to point out here that, while nobody can violate security (e.g. forge object pointers) inside the VM, with contemporary hardware it will always be possible to hack the OS, machine, security chips, etc etc... and therefore, data extraction is a problem. SL does in fact have the same issues, but LL has been hushed about it. Probably because people never seem to understand this, and love to get upset over it... but really, it's a big fat social problem IMHO, considering what little current tech can do against a very determined Carol.

The solution I think is to use a whitelist (challenge-response), and not to have your skybox, or your banking, in public space (plain sight). Just RL common sense, there. But, but, I'm really getting off track here. The problem I wanted to talk about, and solve, is something different and much worse than peeping toms.

So while I was rambling, Carol has advanced her plans for Sw domination. Now she wants to abuse Alice and Bob's blissfully consistent view of the world. To do this requires no cracking whatsoever—just abuse of the protocol. All she needs to do is send two different messages or responses to Alice and Bob's Sw. The two copies will then slowly desync as the code takes different paths on each side. Obviously this is going to break, but to fix it, we need to know how.

Somewhere along the line, Alice is going to try and effect the inconsistent world... Bob goes "LOLWTF!" )

Which points to a partial solution. What if we could make this situation arbitrarily likely (e.g. extremely likely) to happen with the smallest perturbation? Then we could roll back an arbitrarily short time to the past (requiring arbitrarily little RAM to store the difference), and nobody loses much work. It would also force Carol to run the exact same data and code, or else be found out, even if she runs a second cracked copy for herself.

Essentially, what I'm proposing, is the Halting Problem put to practical use. Message consistency proves with high probability that you ran the same code.

The garbageman knows what you ate for dinner )

This would probably be integrated into some sort of "heartbeat" as a way to keep everyone sync'd within some bounded time. Note that it's also symmetrical. If Alice were to deliberately screw up her hash, Bob might think -she- strayed, and vice versa. To this point, any "accusation" is private. What to do if several peers disagree? Start voting people off the island? (Heheh, sorry. ^..^;)

The thing with voting is that it's only good if you play with several friends, or at least neutrals. But you don't want to play with cheaters anyway, I presume. At the least, you would discover something was up and take your toys elsewhere. The real problem, is if a large gang snuck up on your friends, and all of a sudden, voted you out. Sort of a DDoS... unless maybe you deliberately trusted your friends? Sticky issue.

Hrrrrmm. It's interesting to think about anyways. Let me know what I forgot. n..n
talarubi: (Default)
[2006/04/02, dusk] We just had a tornado tear through the neighborhood. Never seen anything like it. There's negligible damage here, but it took some nibbles and large bites down the street. As far as I know, everyone's alright.

There are few words for the colors and the sky now, much less bit depth in the digicam. But clearly someone scheduled a lightshow, and the storm was the price of admission.
--
Oh, cable's back. We're lucky we didn't lose power and such; lots did. I hope this isn't par for the season. There are more storms this week, and the parents seem less than prepared. o..o
talarubi: (Default)
So some time ago, Microsoft came up with a nice new OO graphics API known as GDI+. While basic, it's a great first step and has essential things like transparency, antialiasing, gradients, image loaders, and a crapload of ways to shuffle data around without excess fussing (GDI+ on a DirectDraw surface? Sure!). It's just generally so much cleaner. There's no more confusing handle selection, and in C++ you can just have local objects on the stack. Very neat.

So naturally I spent a few hours playing around. To my great horror, I find:
1) This is a software engine (no acceleration like the crufty old GDI has).
2) It's doing a bitmap copy or two for, e.g. every DrawLine thrown at the screen!
3) I can watch this happen!!*
4) Resizing the window is slower--recreating Bitmap and Graphics objects incurs visible delays!?

Bwauuuugh! Okay, I get why the compositing is molasses, it's a read/write op, which quickly goes to Video Hell. But I turned that off and it still hardly qualifies as fast.**

Double-buffering, of course, fixes it. For the most part. If my bitmap format matches the screen. But thing is, most office-type apps don't need double-buffering. What they need is fast lines, boxes, text and scrolling (aka big, fast video-side copies)... all inside a fullscreen window, worst-case. Buffering doesn't provide that; AGP is barely fast enough without two or three layers of abstraction in the way. IMHO, that's the biggest reason Java and other "modern" apps feel so slow. If you're running a PCI-E board I bet it's great, but for me, it just lacks the crisp response I associate with native code.

Yeah, yeah, I know... some will say, what's he spewing about, he should buy new hardware! To which I reply, mine works fine, it doesn't need to be in a landfill, and by the way, would they like to donate? :P Ah hell, I really am rambling now. G'nightxx0rs y'all.

* Cue nostalgia regarding my QBASIC days, which has, I realise, now faded. SCREEN 13, baby!
** CompositingModeSourceCopy also disablesneuters antialiasing. And I'm using a Delphi wrapper, not C++. Maybe I'm doing something wrong, I dunno. But clearly DrawLine et al is not CPU-bound, it's just the copies. Google suggests others are running into this too. :(
talarubi: (Default)
Sound familiar? Certain people, including MS now, have been pushing these for awhile (even though XP has always had them). To make a long story short they are basically the equivalent of user ("mortal") accounts under every other OS out there. Linux and Mac folks stuck using Windows will appreciate the ability to not have random worms or stealthware slipping into the Windows folders, hijacking Winlogon, etc, with a few well-placed syscalls. (Vulnerabilities notwithstanding.) Since most apps support it pretty well now, and there are great "SU" equivalents out there, everyone should be using this.

Problem is, if you're just a user at home, it won't do you a lick of good. Oh, sure, it'll probably save you a reinstall. And that's it, because here are some things programs under your limited account still have permission to do (because there was never any way to secure it):

1) Log keyboard and mouse activity;
2) Watch the display;
3) Send messages and requests to other programs running on your login;
4) Talk directly to system services and possibly drivers (but not add/remove any);
5) Debug other programs, rewrite code, prevent them from running;
6) Hook into explorer/common dialogs, effectively denying folder access;
7) Hook other windows syscalls ("user-mode rootkit");
8) Create/Read/write/delete all the files you own, outside of Windows and Program Files (assuming installers were written properly);
9) Make outgoing TCP connections (incoming requires config of Windows Firewall if enabled).
10) ... (Arrrrgh! Wincing yet?)

In other words, you don't have to be Admin to ruin someone's life. You just need an exploit or some good social engineering. Some of this is true under Linux as well, but if you really use it, you already knew that. The real concern is that once Windows Vista makes these limits commonplace, the crackers will adapt. MS (rather, their marketing dept.) will claim they're making Windows more secure, but this is a stopgap, not a real solution. LUA doesn't remove the need for Ad-Aware or virus scanners.

MS and Linux are in a no-win situation here, because fixing the central problems (conflating user with program authority, using blacklists, separating the whitelists from the objects being secured) breaks almost everything out there, even though no one program needs very many permissions. It's so bad that Windows Vista is reported to simulate writes, per-user, to Program Files just to keep legacy apps working!

MS is torn between money (being legacy-compatible for their longtime corporate users) and, more recently, satisfying the security concerns of everyone else. So things are changing, but don't expect airtight computers just yet.
talarubi: (Default)
Anyone remember that crazyass robot in Mario Paint? The thing that held a single measly slot and took a couple minutes just to fecking save?

Well apparently Mario Paint has 32KBytes of saveram on the cart. When I read this I was skeptical... Hmm, I thought, that's enough for one screen, but what about the rest? Well let's find out!

2 * 248x168 pixels * 4/8 bytes/pixel (16 colors) (drawing and animation areas, = 41664 bytes)
+ 256 * 2 (x,y) (animation path = 512 bytes)
+ 16 * 16x16 pixels * 4/8 bytes/pixel (stamps, = 2048 bytes)
+ 96 bars * 3 notes (music, = 288 bytes)
= at least 44512 bytes or 43.5KB

Okay fine, the SNES comes with 128KB of memory built-in. Tons of room for even lavish auxiliary buffers. However, 44KB is almost half again the size of the saveram. What you say!! Well they must be compressing it. Oh ho hooohhh... this gives me evil ideass...

Those of you who tried to be smartarses and .zip your .jpg files (or worse your .zip files :D) before you realised what happened, will see what's coming. No "compression" tool can shrink everything, because if it could, you'd just .zip your .zips until they disappeared into nothing! And then upload your nothing in infinitesimal time! As cool as that would be, the fact is that some data will not shrink, in fact some of it will expand. Namely, the "densest" data, with the fewest patterns (like, say, your .zip files). Data like the canvas to the right.

So for this to work, Nintendo (bless their skimping hearts) need to shrink everything to about 70% of the original size... a reasonable margin. Given the sloooow speed, they are probably using LZW or somesuch—not a favorite of their 3Mhz CPU, but something respectable that will get the job done, and crunch all the simple kiddie drawings, and even then most anything worth saving. But look what happens when you airbrush the whole canvas! Ahahahaaah! Yes, the robot explodes! They even included a helpful message and a little animation. This SO just made my day! ^..^;
talarubi: (Default)
So my current understanding is this.

1) I need normal mouse stuff for the GUI, but I would like subpixel-accurate strokes for the canvas.
2) To get full-resolution (not screen) coordinates, one has to initialize JTablet with fullControl == 1.
3) fullControl disables automatic mouse-movement by the pen.
4) So fine. I run a background thread to handle the tablet, mouse cursor and stroke notifications.
5) The canvas needs to work with the mouse, too.
6) Thus the canvas gets both real mouse events and fake ones from the tablet thread.
7) The thread can't afford to notify synchronously; if it did the cursor would be jerky.
8) So there's no way to tell the real and fake events apart! Way to screw up the drawing.

*scratchscratchscratch...*
One way to fix this would be to ask if the pen is currently over the tablet. But JTablet conveniently left that function out! So maybe there's another hack... hrmmm..

Another idea is to increment a counter for every event in the tablet thread and decrement it (to zero) after every mouse event goes through. However this depends on the GUI code to keep things running smoothly, and the user not moving the mouse at the same time too. :-) Anyway it was finicky and only worked half the time.

I suppose I could turn off manual mouse-movement whilst the cursor is on the canvas. However this presents the nice catch-22 that the cursor will never leave it. Would have to continually check hover events to be sure.

Or I could merge all handling into the mouse events, and *if* the cursor is near the last tablet coordinate, use the latter. That begs for race problems, but minus this hack, it looks like it's the way JTablet was meant to be used.

Option five is to stick with pixel coordinates. This is usable, I guess. Otherwise, modifying/replacing JTablet might just be better in the long run.

Edit: I see what's up. Turns out the tablet driver requires a window so it can send you notifies. Except JTablet hands it the system desktop, which will just ignore them! Pretty rude, too, since it could break newer Windows versions. But Java/Swing doesn't exactly LET you get at your app's window, so what to do? Yet another hack (albeit would be simpler than the above crap)!
Page generated Jun. 17th, 2025 02:52 pm
Powered by Dreamwidth Studios