Articles By landon, page 1
My new project: Cube IRC
Posted on January 18th, 2012 17:23:18
by landon
Comments
What is it?
Cube IRC is a 3d IRC client that I've been working on for the last two weeks off and on. What I want to do is be able to connect to a chat room and visualize what's going on. Who are the frequent talkers? Who is lurking? Who are the talkative groups? Right now the client isn't at the stage where I can answer those questions, but it does connect to a room and create an avatar for everyone joining the room and talking in it.
The architecture
(so far)
Working with threads
There are two major elements so far, the graphics thread and the IRC thread. Threading is implemented using boost::thread, which ended up being very simple. The program starts off initializing the graphical client and setting the parameters of the IRC client, which is then started. Communication between the two threads is handled with a message queue that passes every IRC event to the graphics thread. The upside of this method is that it is very simple, but the downside is that the graphics thread has to do all the processing, the IRC thread only keeps state as much as it needs to to stay connected to the server.
IRC
The IRC client is implemented with libircclient in a custom C++ wrapper. There's not much more to it other than a configuration file read in using Ogre::ConfigFile. Currently there is support for joining a single server and multiple channels, although the graphics side does not really differentiate between channels. That's one more hurdle to jump, how I am going to deal with a user that is in more than one channel.
Graphics
I'm using Ogre3D for the graphics side of the client. Every time someone on IRC joins or talks to the channel, an avatar is created and if necessary a chat overlay will pop up over their head. When they quit the server or part a channel, the corresponding model is deleted. Right now this side doesn't have much depth, because most of my time spent so far was getting the basics to work, such as thread communications and popping up an overlay to represent a line from IRC.
Future Plans
I would like to use some of the animations available in the current model and attach those to specific phrases, such as starting the dancing animation when someone mentions dancing in the channel. I also want to have some sort of AI in the avatars that moves them closer to avatars they're addressing, but still maintaining a distance and not colliding with others. Also, ideally, when someone joins the channel, the avatar should enter from a "doorway" and walk over to their default position.
The Goods
Screenshots of current progress
Sooner or later I'll open up the git repo as well.
An LCD Gotcha
Posted on October 17th, 2011 12:38:08
by landon
Comments
Last week I posted some AVR gotchas, but now it's time for an LCD gotcha!
<rue_shop2> Landon, for over 6 years, everyone who gets a hd447880 screen has written their own library
Yep, that's what I did. I wrote some LCD helpers in assembly for this project. The big problem I encountered was my strings were getting truncated when I read them from the EEPROM and displayed them on the LCD. After verifying my EEPROM code was correct, I turned to my LCD code. I had just switched to waiting on the Busy Flag of the LCD instead of a max delay.
Assuming all of my ports are set up correctly (PortD6 is the Enable line of the LCD)
STILL_BUSY:
sbi PORTD, 6 ; enable
nop
in R16, PIND ; read in Data7 (attached to PortD3)
cbi PORTD, 6 ; disable
andi R16, 0x08 ; mask out all but pin 3
brne STILL_BUSY
Ok, you might not see the problem yet. Let me give you some more information. I was also working in 4 bit mode. Look again.
The gotcha is that with 4 bit, reads need to be done twice, otherwise you'll be reading part of the current address next time you strobe the Enable line. Duh! This wasn't apparent in the article I was using though, because 4 bit mode was almost an afterthought in the microcontroller implementation and there was no way you would be punching buttons fast enough by hand to need to wait on the Busy Flag.
Corrected code:
STILL_BUSY:
sbi PORTD, 6 ; enable
nop
in R16, PIND ; read in Data7 (attached to PortD3)
cbi PORTD, 6 ; disable
rcall PULSE_ENABLE ; need to call twice, because of 4 bit mode
andi R16, 0x08 ; mask out all but pin 3
brne STILL_BUSY
Common AVR Gotchas
Posted on October 10th, 2011 10:24:06
by landon
Comments
I'm going to list a few gotchas I encountered this weekend while fiddling around with my AVR projects.
The first:
Interrupts don't happen unless they're... enabled. I spent too long trying to figure out why the timer overflow in my previous test worked, but the timer compare match in my current test didn't. The reason it didn't work? Somewhere in there I had deleted sei from my init code. That's right, interrupts are so important that they have their own commands: cli and sei.
The second:
The commands cbr and sbr for registers are NOT the same as their I/O counterparts cbi and sbi. Let's take a peek at the instruction set manual.
CBI – Clear Bit in I/O Register
Description:
Clears a specified bit in an I/O Register. This instruction operates on the lower 32 I/O Registers - addresses 0-31.
Operation:
I/O(A,b) ← 0
This command is straightforward, it takes a bit number as the second operand and sets that bit to 0. Now let's see cbr.
CBR – Clear Bits in Register
Description:
Clears the specified bits in register Rd. Performs the logical AND between the contents of register Rd and the complement of the constant mask K. The result will be placed in register Rd.
Operation:
Rd ← Rd • ($FF - K)
I hope you read the instruction descriptions before blindly using this. In this command the complement of the second operand is ANDed with the register. So that means, while you can get away with cbi PORTA, 1 to clear the second bit in PORTA, you can't do cbr R16, 1 to clear the second bit in R16. Instead, you'll clear the first bit (0b11111111-0b01=0b11111110).
SBI – Set Bit in I/O Register
Description:
Sets a specified bit in an I/O Register. This instruction operates on the lower 32 I/O Registers - addresses 0-31.
Operation:
I/O(A,b) ← 1
This one is straightforward just like cbi.
SBR – Set Bits in Register
Description:
Sets specified bits in register Rd. Performs the logical ORI between the contents of register Rd and a constant mask K and places the result in the destination register Rd.
Operation:
Rd ← Rd v K
Just like cbi and sbi, sbr is the counterpart to cbr and works similarly. Instead of the second operand being a number from 0-7, it is a bitmask as in cbr.
Undoubtedly, I'll have more gotchas when I get back to work on my projects next weekend.
Another blog change
Posted on October 8th, 2011 17:08:25
by landon
Comments
I changed my blog yet again and spent all day copying over posts (hopefully for the last time!)
I'm now using django-articles and have an awesome disqus comment system set up, so have at!
Team Fortress 2: The Sniper
Posted on June 28th, 2011 23:21:32
by landon
Comments
Ok, the Sniper. This is my favorite class in almost every game I play. It lets me take my time, line up my shots, miss them, and finally hit them.
The subtle difference in TF2 from those other games is everything goes so freaking fast. You really have to be a quick draw or a mighty camper to snipe. Also, all of the maps I've played are primarily close quarters or focus-on-the-sniper-over-there quarters.
Starting off, I only have:
- Default Sniper Rifle
- Razorback
- Vintage Jarate
- SMG
- Kukri
My thoughts from the initial 30 minutes?
- Go for a body shot if you're charged up. You're going to miss the head shot.
- Go for a headshot by bringing the scope up after you line up the crosshairs
- Scouts are slippery. I haven't hit one yet.
- Heavies are more clever than they look. They always spot me.
- Snipers are surprisingly choice targets. Unless they're looking at me.
I hope to have a post mortem up later after I've watched a couple of my replays too, so stay tuned!