It is currently Wed Oct 18, 2017 11:48 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 46 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
PostPosted: Fri Apr 07, 2017 1:54 pm 
Offline

Joined: Mon May 27, 2013 9:40 am
Posts: 351
It's common practice. You'll find lots of dirty and ugly stuff in C code for 8 bits :D

_________________
http://www.mojontwins.com


Top
 Profile  
 
PostPosted: Fri Apr 07, 2017 2:25 pm 
Offline
User avatar

Joined: Sat Jan 09, 2016 9:21 pm
Posts: 211
Location: Central Illinois, USA
But there's some dirty and ugly that's that way for a good reason (structs of arrays instead of arrays of structs, global variables instead of lots of function parameters), but I'm not sure there's any good reason to put data in an .h file, is there? I mean, if you really want to #include it instead of compiling it separately, at least name it something else so it's clear that it's not actually a header file.

(Sorry to hijack your thread, Doug)

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


Top
 Profile  
 
PostPosted: Fri Apr 07, 2017 3:02 pm 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1771
Location: DIGDUG
Globals in an .h file are the least of my concerns.

There will be globals. Lots of globals. Where they are defined doesn't interest me. It takes the user 1 extra click to open an included file, if he's interested.

I appreciate your input, na_th_an. It's hard to tell if anyone actually uses my tutorial. The traffic on there is practically nil. I think I had over 90,000 unique visitors in the first month, and last month was 169 visitors. 90% of which see the front page and don't actually click on any real pages.

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


Top
 Profile  
 
PostPosted: Fri Apr 07, 2017 9:41 pm 
Offline

Joined: Fri Dec 27, 2013 4:28 pm
Posts: 54
I actually just used your post on mmc3 bankswitching to figure out how to put code/constants/etc into a separate bank for cc65 today. In my case I'm using MMC1 (and the older cc65... I should consider updating) so I adapted it a bit. It definitely helped.

I'm certain I've gotten there from google a few times to remind myself how to do something. I can't recall what for the life of me, but I know I've seen that layout at least a few times. At any rate, it's been helpful before. It's never bad to have more development resources!


Last note, I see you added makefiles for stuff last month. That's cool, I've been getting into using them pretty recently. For some reason I had a crazy time wrapping my head around it, but I think I'm finally getting the idea. Done right, it's really powerful. (Especially for projects with many source files)

You mentioned in your most recent update that linux users had to uncomment things in the makefiles to make things work. This might be obvious, but if you're so inclined, you could remove that step. You could set that as a variable, like REMOVE="rm" then call it like you call $(cc65). It's pretty easy to detect someone's OS - especially if you need to treat Windows specially. You could do something like this:

Code:
ifeq ($(OS),Windows_NT)
  REMOVE="del"
else
  REMOVE="rm"
endif

# ...
clean:
  $(REMOVE) *.nes


I've been tweaking a makefile for something I'm working on super regularly so I thought I'd provide the example in case it's useful. Sorry if that's super obvious, or you just aren't doing it because updating ~20 separate zip files is annoying. At any rate, there it is.


Top
 Profile  
 
PostPosted: Fri Apr 07, 2017 10:17 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5717
Location: Canada
gauauu wrote:
I'm not sure there's any good reason to put data in an .h file, is there? I mean, if you really want to #include it instead of compiling it separately, at least name it something else so it's clear that it's not actually a header file.

It's an extremely common practice and well used convention. I'm sure I've seen it in at least a hundred programs. Here's 1 2 3 examples from the top results of a google search for "binary to C".

Headers like this tend to be included in only one place, though, so there's really no practical problem with it being compiled more than once. (They're certainly not "global" data, in this respect. I'm not sure why you called them that.)

The only objection I can think of is that I guess you consider .h to be semantically reserved for shared code only? I mean, sure that's a convention you can insist upon if that's your preference, but a whole lot of people have been using it this way for a very long time.

If you want to compare the alternatives, the code itself would merely exchange an #include statement for an extern, so that difference seems lateral to me? It's also adding one more compile operation to the build, as opposed to just an include into the file that consumes it. Overall, I'd expect the extra compile to have a little more overhead but it's probably not a significant issue either way except in some extreme cases... but if you'd like a "good" reason for preferring to #include that might be one.


Top
 Profile  
 
PostPosted: Sat Apr 08, 2017 6:18 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19096
Location: NE Indiana, USA (NTSC)
On forum.gbadev.org, some of the more vocal regulars were sticklers about .h being semantically reserved for header-y things, such as type definitions, function prototypes, extern, and the like.

In addition, at one time, GCC would bloat large const arrays in RAM by orders of magnitude. This means, for example, it'd use 60 MB of RAM at build time to compile an array with 300,000 elements. (Source: DJGPP FAQ) That could become taxing on some of the PCs in use during the early Game Boy Advance homebrew eraa, which were built for Windows 98. Converting the files to assembly language instead of C caused the build process to use less memory. Before the GNU assembler had .incbin, one would use bin2s to save time and RAM compared to bin2c.


Top
 Profile  
 
PostPosted: Sat Apr 08, 2017 6:19 am 
Offline

Joined: Mon May 27, 2013 9:40 am
Posts: 351
When coding in C for such limited platforms, most if not all your variables will be globals - even reusable variables (I, for example, have a bunch of variables defined in the ZP I reuse for common tasks). Of course, having several modules which import the globals they use would be cleaner, but once you get used to be monolithic, it's not such a big deal. cc65 is pretty fast in modern computers and having it compile your game only takes a couple of seconds. I usually have one main.c which includes everything (with things which include things). As long as I do it in the right order, no probs. 99% of my functions take no parameters but read from globals the data they need, even in cases where they are semantically taking parameters. That means that most globals are needed in almost any group of related functions (which I usually keep in the same source file), so the monolithic, just one .c, everything defined in .h, approach is quite fitting.

_________________
http://www.mojontwins.com


Top
 Profile  
 
PostPosted: Sat Apr 08, 2017 12:58 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5717
Location: Canada
tepples wrote:
In addition, at one time, GCC would bloat large const arrays in RAM by orders of magnitude. This means, for example, it'd use 60 MB of RAM at build time to compile an array with 300,000 elements. (Source: DJGPP FAQ) That could become taxing on some of the PCs in use during the early Game Boy Advance homebrew eraa, which were built for Windows 98. Converting the files to assembly language instead of C caused the build process to use less memory. Before the GNU assembler had .incbin, one would use bin2s to save time and RAM compared to bin2c.

If you're only targeting GCC, there's the objcopy utility that can just turn a binary file directly into an object file, and you can bypass any intermediate text format that needs to be compiled/assembled. Not sure if other compiler toolchains have an equivalent.

Of course the ideal thing would be to get some sort of #incbin into the C++ standard so we don't have to worry about which compiler we're using, but it doesn't appear to be on the roadmap as of C++17. So... we continue to convert binary to text and back again, I suppose. The endless toil.

Whether or not you want to put the data in a H or a C file, it's also prudent not to have a large amount of text in a file you need to recompile frequently, of course. (As always, relevant only in specific situations-- in the case of Splatood neither data size nor compile times are an issue.)


Top
 Profile  
 
PostPosted: Sat Apr 08, 2017 7:26 pm 
Offline
User avatar

Joined: Sat Jan 09, 2016 9:21 pm
Posts: 211
Location: Central Illinois, USA
Quote:
(They're certainly not "global" data, in this respect. I'm not sure why you called them that.)


You're right, I'm not sure why I called it that. :-/

rainwarrior wrote:
The only objection I can think of is that I guess you consider .h to be semantically reserved for shared code only? I mean, sure that's a convention you can insist upon if that's your preference,


Well, I'm the new guy around here, so I'll submit to maybe being wrong since most of you seem to disagree with me :)

But yeah, it's all about semantics. .h means a header file, which is for declaration of symbols, not the definition of symbols. Keeping that consistent makes it easier for humans (and tools) to understand your code. When I'm looking at a codebase, I expect a header file to give me an overview of the function call api. Having a bunch of data confuses that.

Which is why I'm not arguing against #include'ing data. I don't care if you #include everything into one big file. I just think calling your data a .h file is horribly confusing, and semantically incorrect.

Quote:
but a whole lot of people have been using it this way for a very long time.


I would contend that they've been doing it wrong for a long time. But whatever, like I said, I'm willing to be wrong :)

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


Top
 Profile  
 
PostPosted: Sat Apr 08, 2017 7:28 pm 
Offline
User avatar

Joined: Sat Jan 09, 2016 9:21 pm
Posts: 211
Location: Central Illinois, USA
And Doug, to get back at your original question: I like the level that your example code is at, and don't think you need to simplify it. I find your examples helpful

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


Top
 Profile  
 
PostPosted: Sun Apr 09, 2017 4:49 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1771
Location: DIGDUG
Oh, I'm not going to overwrite the current pages, I'm going to expand (maybe) with some kind of neslib-like examples.

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


Top
 Profile  
 
PostPosted: Sun Apr 09, 2017 5:22 pm 
Offline

Joined: Sat Oct 15, 2016 8:52 am
Posts: 77
Hi Nesdoug, just a quick comment - I don't know about anyone else, but I certainly used your tutorials and found them extremely helpful. Thanks for writing them!

From what I remember the first two or three just set everything up in terms of basic graphics, and I think your style is not to explain everything, but to explain key parts and then provide a complete working example. I think this works well already and is not too overwhelming.

I discovered them in the middle to late to last year, but from the structure I presume they arose very organically? If you were to redo any of them, it might be an idea to more cleanly separate the early tutorials, which build post on post in terms of skills and understanding, from the spacy mcshooty stuff, which is more like a devblog and less something someone could follow along with.

It's a great wealth of information and I often find myself digging in it for something I half remember reading, so thanks!

On the other theme of this thread, I've been using header files as more or less complete libraries - so all my tile routines are in one, for example, with their own global variables that are used exclusively for them. Is this considered poor practice? It's a little wasteful (in that I'm using 20 odd variables that could be reused elsewhere in the code) but it does mean everything is self contained and makes testing a lot easier.


Top
 Profile  
 
PostPosted: Sun Apr 09, 2017 7:03 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5717
Location: Canada
gauauu wrote:
Well, I'm the new guy around here, so I'll submit to maybe being wrong since most of you seem to disagree with me :)

But yeah, it's all about semantics. .h means a header file, which is for declaration of symbols, not the definition of symbols. Keeping that consistent makes it easier for humans (and tools) to understand your code. When I'm looking at a codebase, I expect a header file to give me an overview of the function call api. Having a bunch of data confuses that.

Which is why I'm not arguing against #include'ing data. I don't care if you #include everything into one big file. I just think calling your data a .h file is horribly confusing, and semantically incorrect.

I don't think of your idea as wrong: it's a correct consequence of that semantic choice. I just think it's a choice, though. It's very common practice to do otherwise, and not normally harmful in any obvious way. There are plenty of people who share your preference, too.

Inline definitions have always had to be included with a header in C, and C++ doubled down on that with templates. (Open any STL header for an example.) I've seen some projects with a convention that puts inline definitions in yet another file (with a custom extension) included from the header instead.

I've even seen others try to do away with header files, and write some sort of processor program that automatically converts an intermediary ".cpp with annotations" file into cpp + headers as part of the build process. Kind of a simulated Java style, I guess?


Top
 Profile  
 
PostPosted: Mon Apr 10, 2017 2:12 am 
Offline

Joined: Mon May 27, 2013 9:40 am
Posts: 351
I think gauauu is 100% right on what he says, but once I started coding for 8 bits platforms in C, I had to forget about readability, proper use of semantics, good practice and readability if I wanted to get proper results.

_________________
http://www.mojontwins.com


Top
 Profile  
 
PostPosted: Mon Apr 10, 2017 8:13 am 
Offline
User avatar

Joined: Sat Jan 09, 2016 9:21 pm
Posts: 211
Location: Central Illinois, USA
na_th_an wrote:
I think gauauu is 100% right on what he says, but once I started coding for 8 bits platforms in C, I had to forget about readability, proper use of semantics, good practice and readability if I wanted to get proper results.


Well, everything I've done on 6502 is in assembly so far, so maybe once I start doing some C, I'll find out that my strict ideas won't work :D

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


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 46 posts ]  Go to page Previous  1, 2, 3, 4  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 guests


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