freeware follies

Discuss popular GCS tools like ZZT, Megazeux and Adventure Game Studio, as well as programming and other topics related to game design.
Post Reply
pseudocoder
Experienced Member
Experienced Member
Posts: 76
Joined: Sun Nov 23, 2014 6:16 pm

freeware follies

Post by pseudocoder »

First and foremost, I want to thank Tien for sharing his source - without it, I wouldn't have tried making a game. I'm not a programmer and have no knowledge at all of assembly, but found all of these little demos fascinating to work with. I'm okay with C, I suppose, but have no formal coursework or such.

For grins, I took a stab at making a space shooter of sorts; it doesn't do much, but one can fly about a few pixels shooting at a few other pixels. For anyone interested, I've posted the source along with an executable on my page since there doesn't seem to be any anonymous free uploading anymore.
User avatar
tienkhoanguyen
PSEUDOCODER
Posts: 2664
Joined: Fri Sep 05, 2014 9:43 am
Location: Texas

Re: freeware follies

Post by tienkhoanguyen »

pseudocoder wrote:First and foremost, I want to thank Tien for sharing his source - without it, I wouldn't have tried making a game. I'm not a programmer and have no knowledge at all of assembly, but found all of these little demos fascinating to work with. I'm okay with C, I suppose, but have no formal coursework or such.

For grins, I took a stab at making a space shooter of sorts; it doesn't do much, but one can fly about a few pixels shooting at a few other pixels. For anyone interested, I've posted the source along with an executable on my page since there doesn't seem to be any anonymous free uploading anymore.
Thank you! What a beauty. The game is made professionally. I would never imagine my source code would inspire someone to go so far!!!!!!!!!!!! You are going places. I am proud of you!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! I wish I could do as nice of a touch as you have shown here in your game.
God, Jesus Christ, is number one!hehe
Jesus Christ!hehe
Bless Jesus Christ!
Then please bless my mom.
Honour to my mom Huong Thi Vu
Honour to my dad Thuy Binh Nguyen
Love to cousin Carl Anh Cuong Cao Vu
Thank you Jesus Christ.
User avatar
MrFlibble
Demoniac Demo maniac
Demoniac Demo maniac
Posts: 3733
Joined: Sun Dec 05, 2010 11:39 am

Post by MrFlibble »

Haha, this is cool ^_^ I didn't figure out how to shoot though but Tien is right, the game looks pretty polished, even with minimalist graphics. Great job!
User avatar
tienkhoanguyen
PSEUDOCODER
Posts: 2664
Joined: Fri Sep 05, 2014 9:43 am
Location: Texas

It also uses one of the Microsoft or SONY controllers.

Post by tienkhoanguyen »

I was able to shoot I think using the SONY PSone controller with USB adapter. I did not try the Microsoft XBOX360 USB controller though for this game.

[edit: I just tried the Microsoft XBOX360 USB controller and it doesn't work. Just the SONY PS1 controller with USB adapter works fully. The keyboard works however is not as smooth as with the SONY controller! I don't know how to shoot with the keyboard either.]
God, Jesus Christ, is number one!hehe
Jesus Christ!hehe
Bless Jesus Christ!
Then please bless my mom.
Honour to my mom Huong Thi Vu
Honour to my dad Thuy Binh Nguyen
Love to cousin Carl Anh Cuong Cao Vu
Thank you Jesus Christ.
pseudocoder
Experienced Member
Experienced Member
Posts: 76
Joined: Sun Nov 23, 2014 6:16 pm

Post by pseudocoder »

Thanks guys; I'm glad it appeared to work. :)

Oops; the sandman got me before I thought to post controls. To move, w,a,s,d or arrow keys and use f to fire. Escape or q to terminate, and r to restart. I think other keys may work to restart too.

@tien: I took out the code for joystick 2... is that one that works with the Xbox controller? I used the PS1 connected through the usb adapter. The keyboard can be sped up a bit through the RATE macro in the source. To adjust rates on the user end, a config file could be implemented.

For the gamepad, I found that only triangle and circle on the PS registered. The two could also be pressed together for a "third" button. Is that what it's supposed to do or did I botch something? A bit mask maybe?

I'm still perplexed by what's going on with the DB SEG:OFFSET for sprites stuff. I have an idea of what it is, but not to the point where I can code it in C style arrays. The Borland I used doesn't seem to like the jmp labels in asm statements much either as the sprite based data block functions spit out compiler errors

I'll try sound next, I think.

Cheers.
User avatar
tienkhoanguyen
PSEUDOCODER
Posts: 2664
Joined: Fri Sep 05, 2014 9:43 am
Location: Texas

God, Jesus Christ, is number one!hehe

Post by tienkhoanguyen »

Jesus Christ!hehe
pseudocoder wrote:Thanks guys; I'm glad it appeared to work. :)

Oops; the sandman got me before I thought to post controls. To move, w,a,s,d or arrow keys and use f to fire. Escape or q to terminate, and r to restart. I think other keys may work to restart too.

@tien: I took out the code for joystick 2... is that one that works with the Xbox controller? I used the PS1 connected through the usb adapter. The keyboard can be sped up a bit through the RATE macro in the source. To adjust rates on the user end, a config file could be implemented.

For the gamepad, I found that only triangle and circle on the PS registered. The two could also be pressed together for a "third" button. Is that what it's supposed to do or did I botch something? A bit mask maybe?

I'm still perplexed by what's going on with the DB SEG:OFFSET for sprites stuff. I have an idea of what it is, but not to the point where I can code it in C style arrays. The Borland I used doesn't seem to like the jmp labels in asm statements much either as the sprite based data block functions spit out compiler errors

I'll try sound next, I think.

Cheers.
For the most part, most of the assembly stuffs in there are for routines that C would not easily do. However it is possible in C. I have pre-built these routines with Quadko's help especially the gamepad routine.

So if you want the Microsoft XBOX360 USB controller to be used you just have to plug in the other gamepad routine that you mentioned.

The DB SEG:OFFSET is specific to how the memory is arranged in MS-DOS. For instance, SEG 4096 would give the number so the computer would recognize for each 64k, and the OFFSET 4096 would give the number the computer would recognize for under 64k. Something along that line anyways. DOS has a maximum of I think 1 Megabyte to use. You can only access 64k at a time. So each 64k is called a segment.

I am not sure how to explain it, I just know how to use it. Quadko explained it to me once and ever since I just know how to use it and understand it. However I cannot explain it. Maybe Quadko could shed some light for you?

The reason it is in assembly is because it was once coded in C and it was not fast enough. For a little trivia, the fun thing is that these prebuilt assembly routines are so useful that you never have to really code anything else in assembly. haha

The reason you are seeing errors must be warnings. I leave the warnings there just in case I wanted to actually use that variables. However it just warns you that the variables you are using is not actually used in the game.

Thank you Jesus the hard part of my coding is done!!!!!!!!!!!!
God, Jesus Christ, is number one!hehe
Jesus Christ!hehe
Bless Jesus Christ!
Then please bless my mom.
Honour to my mom Huong Thi Vu
Honour to my dad Thuy Binh Nguyen
Love to cousin Carl Anh Cuong Cao Vu
Thank you Jesus Christ.
User avatar
Quadko
Darklander
Darklander
Posts: 2092
Joined: Fri Jun 24, 2011 10:07 am

Post by Quadko »

I'm still perplexed by what's going on with the DB SEG:OFFSET for sprites stuff. I have an idea of what it is, but not to the point where I can code it in C style arrays.
I'm happy to try if there is anything I can clarify. I'm not sure the context, but just ask if you want!

The only secrets I know are that C hides the complexities during compilation, but that real memory in dos is divided into 16 byte "segments". Every time you add 1 to a segment value, you are 16 bytes further along in memory. Offsets allow you to access each byte, so seg:offset can give you each byte - 100:10 is segement 100, 10 bytes in, or 100 * 16 + 10 actual memory byte. And offsets can be large (16 bit? 64k? IIRC), so you can set a segment and access 64k bytes just by changing the offset. The C compiler stuff mostly assumes you have "small" arrays that fit inside 64k so you just have 1 pointer that's an offset into the standard 64k data segment (unless you do special stuff to tell the compiler otherwise), but with advanced C tricks or just in assembly you can do anything you want.

If you're comfortable with Hexidecimal numbers, it's easy since the last digit is controlled by the offset: Memory location 0x30021 is 0x3002:0x1, or 0x3000:0x21, same memory location but different ways to describe it with SEG:OFFSET pairs.

It basically still works that way in modern 32bit apps, but since 32 bit numbers can reference 4 GB of memory, we never really have to deal with segments any more, just the offset pointer. (And same scaling up with 64 bit processors and 48 & 64 bit memory addressing.)

No idea if that releates to your actual question, but figured I'd put the basics in there and we'd go from there if you want. :)
pseudocoder
Experienced Member
Experienced Member
Posts: 76
Joined: Sun Nov 23, 2014 6:16 pm

Post by pseudocoder »

Thanks Quadko; I appreciate the time and explanation. My problem has always been being fundamentally weak in the underlying lanaguage. I know zilch about standards, memory management, cpu registers, and whatnot. I've learned to get by on things that I've picked up in tutorials, and helpful souls.

I'm okay with file operations, hex, PODs, basic pointers, and so forth, but never understood linked lists, and things like that, so I've avoided dealing with them.

As far as the segment:offset goes, I think I understand it, but have to relate to it in laymans terms. For example, indexing to a desired position within an array.

With the sprite question, Tien had a function that declared sprite data along with functions that loaded and removed the sprites. I wanted to replace the DB directives with a flat array. I also wanted to make two generic functions that loaded and removed the sprites; however, I didn't understand some of the asm directives or what they did - namely, the segment and offset and push / pop. I know what push / pop does, but not why it was used in terms of the registers.
User avatar
tienkhoanguyen
PSEUDOCODER
Posts: 2664
Joined: Fri Sep 05, 2014 9:43 am
Location: Texas

God, Jesus Christ, is number one!hehe

Post by tienkhoanguyen »

Jesus Christ!hehe

Well, I think I still remember this part? The way my assembly sprite routine works is as follows. It plots the picture exactly as it is drawn in the DB section. When you want to do a transparent sprite, just do "storesprite1(y, x);" That is the first thing... to store what was underneath the sprite. Then when you plot by "plotsprite1(y, x);" you have your sprite and the graphics underneath is still there stored already with the first command "storesprite1(y, x);". Now after you have paused it for like a count of say 12000 (twelve thousand) you would "restoresprite1(y, x);" This just puts the original background graphics back. So you did not mess up say a tree in the background.

The push and pop is for assembly language. Since in assembly language you only have a limited amount of variable which they call registers you have to push it onto a storage area called a stack. Then when you want to recall that variable you pop it off the stack. However you have to follow the FILO rule. First In Last Out. This is the opposite of how Walmart does their stocking. If you go to Walmart, you notice the people who work night shift stock. They should be putting the new stuffs behind so the old stuff does not get stale. So the customers who are smart should usually check the date and take from the back which is the freshest. Anyways, in computer assembly it is the reverse. You put the stock in first and it keeps piling up new stuffs in front. So you have to take from the front until you reach the very back.

An example of assembly using push and pop is as follows:

Push AX
Push BX
Push CX

do you stuffs here with AX, BX, CX and mess up those registers with new values

Pop CX
Pop BX
Pop AX

(now you have just restore your original AX, BX, and CX with pop off stack. Notice the reverse sequence from A, B, C then C, B, A? That is how it is accessed. Cappish? hehe)

I'm joking but it took me a lot of headache to get it.
God, Jesus Christ, is number one!hehe
Jesus Christ!hehe
Bless Jesus Christ!
Then please bless my mom.
Honour to my mom Huong Thi Vu
Honour to my dad Thuy Binh Nguyen
Love to cousin Carl Anh Cuong Cao Vu
Thank you Jesus Christ.
User avatar
Quadko
Darklander
Darklander
Posts: 2092
Joined: Fri Jun 24, 2011 10:07 am

Post by Quadko »

Makes sense. :) In assembly, Push (register to memory) and Pop (memory to register) is all about controling the values of the registers, saving or loading them from memory. (Well, from the stack; you can also set them to random memory values.) In higher languages like C you don't have to worry about it, of course. But basically the CPU can't do anything like adding or changing values directly in RAM memory, it has to load the value to one of the limited CPU Memory "registers" to do anything. So most commands are "load these registers, do some operations, save results back to memory". The stack and push & pop are quick ways to do more complex series of operations, with a stack area in RAM memory set aside for storing these setup or intermediate register values. Even moving from one RAM memory location to another is "load memory to a register, save that register to different memory". Just the way processors work. Fun, yes?! :huh:

And can't directly help you with tien's code, but happy to answer any questions and add my opinions and translations to the mix. Happy coding!
pseudocoder
Experienced Member
Experienced Member
Posts: 76
Joined: Sun Nov 23, 2014 6:16 pm

Post by pseudocoder »

@Tien: thanks for passing along what the routines did - I appreciate it. I got a bit confused by

Code: Select all

PUSH AX
PUSH BX
PUSH CX

do stuff with AX, BX, CX

POP CX
POP BX
POP AX
The reason being if you push the old values on the stack, then wrote new data in the registers, wouldn't it affect the stack before being able to retrieve the old values? That's what I don't quite get. I guess it keeps some internal place holder?

Thanks again. :D

@Quadko: I appreciate the help and explanations - they are a big help; Over the years of this madness, I think I've learned just enough to get myself in trouble... Win 2k / XP uncrashable?? yeah, that was before they met me. :P
User avatar
tienkhoanguyen
PSEUDOCODER
Posts: 2664
Joined: Fri Sep 05, 2014 9:43 am
Location: Texas

God, Jesus Christ, is number one!hehe

Post by tienkhoanguyen »

Jesus Christ!hehe

Well, that should be easy for you to remember. The stack is actually a separate place in memory. It is uaually stored I believe at the end of your program. So for instance, say the first 10 lines are your game coding. The stack is set aside a fix amount after that. In assembly you have tell it how much to set aside. However, I guess C does it automatically for you.

So when you push AX, it goes to say line 11 which is pass your program and stores it there. In reality, I think it is done backwards from the top of the stack. So if you set say 10 lines of stack. It will start from line 20 in this case and go down until it reaches line 10. [However, stacks can be set in any place in memory like Quadko said.]

There are a few separate pointers. The reason the value doesn't get affected is because there is a stack pointer which points to the area to be affected when you PUSH and POP. Then there is a program or (IP - Intruction Pointer) points to the current run line of your coding. Since there are two pointers (at least), the stack pointer and the instruction pointer, the computer doesn't get confused by which line is currently running and where the stack is being stored or retrieved.

The AX, BX, CX, and DX is simply most commonly related to variables like in C you would declare it as:

int AX, BX, CX, DX;

AX = 12000;
BX = some other number;
CX ...

Unlike variables, it is a fix variable that is always there and limited to these 4 (AX, BX, CX, and DX). That is why assembly takes so many lines to code. You have to work with the basics of the chip itself. The chip is just zero and one for off and on. Assembly is very close to that.

I hope that explains what you are looking for a little more.

Thank you Jesus I still remember these stuffs and not seen as a looney. haha
God, Jesus Christ, is number one!hehe
Jesus Christ!hehe
Bless Jesus Christ!
Then please bless my mom.
Honour to my mom Huong Thi Vu
Honour to my dad Thuy Binh Nguyen
Love to cousin Carl Anh Cuong Cao Vu
Thank you Jesus Christ.
Post Reply