It is currently Wed Sep 18, 2019 4:37 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 14 posts ] 
Author Message
PostPosted: Wed Feb 06, 2019 6:52 pm 
Offline
User avatar

Joined: Wed Jan 16, 2019 9:13 pm
Posts: 17
Location: Lower East Side
There are some interesting notes folks have shared about the decision-making process folks go through when considering whether to write a game in C or assembly.

Can anyone share a specific example of a game (or part of a game) you wrote in a language other than assembly? Explain why you chose to write it in that language. Links to source code would be cool if you can share!

For context: I've learned a good amount about writing a game in assembly, so I'm wondering if I should consider writing any parts of a game in a higher level language.


Top
 Profile  
 
PostPosted: Wed Feb 06, 2019 6:57 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 4208
Location: A world gone mad
I haven't written any games on the NES, or any non-games on the NES that haven't been in assembly.

That said, I will mention this one particularly wonderful creation from someone else: making NES stuff in CLISP: https://ahefner.livejournal.com/20528.html


Top
 Profile  
 
PostPosted: Wed Feb 06, 2019 7:02 pm 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1904
ericandrewlewis wrote:
Can anyone share a specific example of a game (or part of a game) you wrote in a language other than assembly?

I wrote my game "City Trouble" in C, except for a few low level functions. Why did I do it? Because I wouldn't have had the patience to tediously write a game in Assembly. I've been programming in C-like languages since 2001 and I work as a professional software developer, but writing a whole game in Assembly would have been a hassle. I need much longer to read Assembly code than C.

I'm also writing my current "Zelda"-like action adventure in C, although due to necessary optimizations, I had to turn a bunch of stuff into inline Assembly. Which I simply create as C macros, so it's still miles away from actually writing the game in pure Assembly. Most stuff is still in C.


One advantage of C over Assembly that I encountered during the production of "City Trouble":
When I discovered that my y coordinates for game characters don't need to be an int, but can be a single byte, I simply had to change the data type. And suddenly, a whole bunch of ROM was now unused and free to be filled with other stuff. In Assembly, I would have had to search for every occurence of the y coordinates and change the handling manually.

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Wed Feb 06, 2019 7:25 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7582
Location: Canada
I've made two NES releases that were mostly programmed in C:

Why? It's easier, and takes less work. There's less code to write, and there's less code to read and debug.

The important advice I'd have here is to continually measure performance. It's not hard to accidentally write some C code that takes way too long to execute. When that happens, you need to look at the assembly output and figure out either a different way to write it in C that compiles into better code, or just rewrite that part directly in assembly.

It's much faster for prototyping and trying ideas, even if you have to rewrite it in assembly once you're done experimenting.

I have another NES release that was originally written in C++ (not for NES) and ported to NES.

Even here it helped a lot to use C++ first. Working out all the details and revisions of logic is much easier and faster in the high level language. Once the C++ became stable, I'd rewrite those stable parts in assembly to try on the NES, and this made it so I rarely had to do iterative work in assembly. Cutting out the work of trying many revisions of assembly code makes a big difference.


Top
 Profile  
 
PostPosted: Wed Feb 06, 2019 7:40 pm 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 2562
Location: DIGDUG
See my signature for link to source code.

After using both c and asm. I'd say that the programming part of development is 2x as fast in C. Less to write, easier to read.

(edit) of course the code generated is 2x as long and 1/2 as fast.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Last edited by dougeff on Wed Feb 06, 2019 7:45 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Wed Feb 06, 2019 7:42 pm 
Offline
User avatar

Joined: Thu Aug 13, 2015 4:40 pm
Posts: 418
Location: Rio de Janeiro - Brazil
I was just about to post about your tutorials. I have never written a line of code in C, but I feel like I'm missing out. ASM is getting too abstract for me to handle. I will read through your tutorials once more, but this time trying to learn some C and get something done. If it helped me write in assembly, I'm sure it'll be even easier to just follow it as intended.

_________________
https://twitter.com/bitinkstudios <- Follow me on twitter! Thanks!


Top
 Profile  
 
PostPosted: Wed Feb 06, 2019 8:06 pm 
Offline
User avatar

Joined: Fri Nov 24, 2017 2:40 pm
Posts: 170
With a little tender loving care, you can write C that generates decent assembly. You will *always* be able to beat cc65 in both size and speed. It's not that it's a bad compiler per se, but that it's a little hobby compiler maintained by volunteers. Also C was conceived with 16 bit UNIX machines in mind IIRC. Sometimes it can be hard to convince cc65 that it doesn't need 16 bit temporary values.

I usually start with C code to get something working, but a lot of my final code ends up as assembly once I know what I want to do. Assembly can't tell you if you are passing function parameters wrong, or if you are doing comparisons wrong etc. C isn't a very safe language, but assembly has no safety.


Top
 Profile  
 
PostPosted: Wed Feb 06, 2019 8:36 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 21591
Location: NE Indiana, USA (NTSC)
ericandrewlewis wrote:
Can anyone share a specific example of a game (or part of a game) you wrote in a language other than assembly? Explain why you chose to write it in that language. Links to source code would be cool if you can share!

I chose to write all my Game Boy Advance games (Vitamins, Luminesweeper, and a couple others) and non-games (such as 160p Test Suite) in C for a couple reasons:

  1. One of the games was also made for PC, and I wanted to share game logic and menu logic between the two such that bugs fixed in one get fixed in the other.
  2. I found GCC's output targeting Thumb good enough, and I didn't want to spend unnecessary time learning yet another assembly language. (I acknowledge that nocash might disagree, and this doesn't apply nearly as much to the output of cc65 or SDCC.)

I tried C++, but even a Hello World example using iostream ate up most of the GBA's RAM with unused date, time, and currency formatting code that GNU libstdc++'s output stream implementation instantiated by default. Though this may prove tolerable in a cartridge game, I found it impractical for multiboot. I consider multiboot important for two reasons: single-Pak multiplayer and the fact that for a long time, the GBA Movie Player was the easiest flash cart to acquire.

As for writing NES games specifically in C, I'd probably do so mostly as a test case for ensuring that libraries that I have written in assembly language would correctly integrate with others' games written in C.

See also "To C or not to C?" by ISSOtm. It's about SDCC, which targets the Z80 and the Game Boy CPU, but a lot of the core concepts apply just as much to cc65.

_________________
Pin Eight | Twitter | GitHub | Patreon


Top
 Profile  
 
PostPosted: Wed Feb 06, 2019 9:37 pm 
Offline

Joined: Wed Nov 30, 2016 4:45 pm
Posts: 146
Location: Southern California
Quote:
For context: I've learned a good amount about writing a game in assembly, so I'm wondering if I should consider writing any parts of a game in a higher level language.

Beyond what others have said, you can dramatically raise the level of assembly language by using macros, making the source code much shorter and easier to read and maintain, producing fewer bugs, and doing it with (in most cases) absolutely no penalty in the final run speed or memory taken. Beware however macros have been used poorly by many, resulting in a lot of invalid advice against macros.

Here's a simple one to start. When you have to copy a 2-byte variable from one place to another, you usually get this:
Code:
        LDA  VARIABLE1
        STA  VARIABLE2
        LDA  VARIABLE1+1
        STA  VARIABLE2+1

It keeps coming up; so why not make it a macro that assembles exactly the same thing:
Code:
        COPY2  VARIABLE1, TO, VARIABLE2


Code:
        DISPLAY_IMM   "Press ENTER to begin"
        WAIT_FOR_KEY  ENTER_KEY
is more readable and intuitive than
Code:
         JSR   DISP_QUOTE
         BYTE  dim2#-dim1#                 ; Lay down the string length byte,
 dim1#:  BYTE  "Press ENTER to begin."     ; followed by the string.  (Counted string, not nul-terminated.)
 dim2#:  JSR   INPUT_KEY
         CMP   #KEY
         BNE   dim2#
but assembles the same thing.

You can do conditionals and looping controls (etc.) too. Here's a simple one:
Code:
        CMP  #14
        IF_EQ
           <actions>
           <actions>
           <actions>
        ELSE_
           <actions>
           <actions>
           <actions>
        END_IF

(Note there are no labels necessary.) "<actions>" can be any assembly-language instructions, more macro invocations, and even nested IF structures. In the structure above, the IF_EQ assembles a BNE to the first instruction after the ELSE_. It won't know that instruction's address yet, so it puts its own address on a stack in the assembler itself, then ELSE_, when encountered, will calculate the branch distance and go up and fill in the operand for the IF_EQ. ELSE_ then does a similar thing so that END_IF can fill in the right operand for ELSE_. ELSE assembles a JMP (or, for the 65c02, an unconditional branch, BRA) down to the END_IF. END_IF does not add any code, only fill in the operand for the instruction laid down by ELSE_. And again, these are nestable. IOW, you could have one IF...END_IF inside another one, many levels deep, and each one will branch to the right place.

How about a looping one:
Code:
        LDX  #8
label:  <do stuff>
        <do stuff>
        DEX
        BNE  label

can be made more clear (although not much shorter) by writing it this way:
Code:
        FOR_X  8, DOWN_TO, 0
           <do stuff>
           <do stuff>
        NEXT_X

and the resulting machine code will be exactly the same. (Note that the FOR...NEXT works slightly differently from how BASIC does. Just keep in mind how the assembly language works, that the decrement (DEX in this case) comes before the conditional branch (BNE in this case) to the top of the loop; so the loop will get run for 8, 7, 6,...1, but not 0, since it will drop through on 0.)

I have lots more of these, plus some accessory macros for example RTS_IF_MINUS in my article at http://wilsonminesco.com/StructureMacros/, and extended code examples in the last 40% of the page on simple multitasking without a multitasking OS, at http://wilsonminesco.com/multitask/index.html . There's additional explanation of how to form the structure macros, in the section of my 6502 stacks treatise on forming nestable structures, at http://wilsonminesco.com/stacks/pgmstruc.html .

So again, you can become much more productive in assembly language, and get code that is more readable and maintainable, and less buggy, and in most cases there will be absolutely zero penalty in performance or memory taken, unlike the situation with higher-level languages. It sure increased my own enjoyment of assembly, a lot!

_________________
http://WilsonMinesCo.com/ lots of 6502 resources


Top
 Profile  
 
PostPosted: Thu Feb 07, 2019 12:51 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7741
Location: Chexbres, VD, Switzerland
When it comes to NESDev, I have only used CC65 once for a test, and the test was not very satisfying as it resulted quickly in calculations that would take more than one frame to make something simple.


Top
 Profile  
 
PostPosted: Thu Feb 07, 2019 8:31 am 
Offline
User avatar

Joined: Sat Jan 09, 2016 9:21 pm
Posts: 625
Location: Central Illinois, USA
ericandrewlewis wrote:
Can anyone share a specific example of a game (or part of a game) you wrote in a language other than assembly? Explain why you chose to write it in that language. Links to source code would be cool if you can share!



My past 2 nesdev compo games (Robo Ninja Climb and Super Homebrew War) have been partially in C. For all the reasons others mentioned (speed of development and ease of reading the code to be able to edit it). Like others said, you have to be careful about performance. Both have significant sections that I rewrote into assembly because I wasn't happy with the C performance.

Source code of Robo-Ninja Climb is available for your perusal.

_________________
My games: http://www.bitethechili.com


Top
 Profile  
 
PostPosted: Thu Feb 07, 2019 9:32 am 
Offline

Joined: Tue Oct 24, 2017 11:07 pm
Posts: 26
What I do is (if the logic is complex enough that writing it in straight assembly would be error-prone) write whatever piece of code I'm adding in a C-like pseudocode and then translate it to assembly once I have the logic down. If the resulting code is hard to understand, I comment it with the corresponding pseudocode. I find that the "writing the pseudocode" part is much more time-consuming than the "translation to assembly and debugging" part.


Top
 Profile  
 
PostPosted: Fri Feb 08, 2019 12:59 am 
Offline

Joined: Mon May 27, 2013 9:40 am
Posts: 543
All my games are in C. It's easy to inject assembly when needed. The main reason is that, in my case, I know the language and developing anything is like 10x as fast.

I've transitioned from pure C to "I find cc65 spits horrible code for this, I'll write my own", which I find both rewarding and useful.

_________________
http://www.mojontwins.com


Top
 Profile  
 
PostPosted: Sat Feb 09, 2019 11:06 am 
Offline

Joined: Fri Dec 27, 2013 4:28 pm
Posts: 85
Pretty much everyone else has already hit the nail on the head with when to choose C over ASM.

In short, while execution time is slower, C code is way simpler than ASM, and thus easier to read and write. (Even with the weird quirks it has) I've run into performance problems a few times, but I generally find that solving them isn't too much trouble. (Running code every other frame isn't too tough, or simplifying things... in rare cases embedding assembly instead.)

I'll admit, I might be the closest NESDev has to a C fanatic. I love doing game jams - competitions held over short periods (usually 48-72 hours or 1 week) where you build a game from scratch. Coding in C has made it feasible to make a fun NES game within that time constraint.


As for projects... I've got quite a few I can share!

- nes-starter-kit (zelda-esque game starter kit)
- NES Puzzle Maker (Puzzle game library/maker with a web frontend - source code not available yet, sorry)
- Closing In: Barney's Daring Escape (Ludum Dare 48 hour coding competition game - Placed 42nd out of 1055 entries)
- Fluffy Space Escape (Puzzle game entered in another Ludum Dare 48 hour competition)
- Missing Lands (Adventure game entered in Ludum Dare -- this came before I started nes-starter-kit!)
- Dizzy Sheep Disaster (Weird one-button control game with a theme of "velcro sheep"... made for BitBitJam #4 over a week)
- Bonus: NESNet A C library (written mostly, but-not-all in assembly) for connecting your NES to the internet


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group