68kMLA Classic Interface
This is a version of the 68kMLA forums for viewing on your favorite old mac. Visitors on modern platforms may prefer the main site.
| Click here to select a new forum. | | C DrawString with parameters? | Posted by: BacioiuC on 2022-09-06 06:24:01 Hi guys,
I'm trying to wrap up my game and I made a ton of mistakes and problems when it comes to using strings with QuickDraw. I wanna clean things up a ton and I'm looking for some help. The only bugs left in the game are related to the log that tells you what is happening. For some reason I get weirdly erratic behaviours when using C2PStr to convert my strings to use with DrawString. So I'm asking you guys for help.
Can anyone help me out with a function that concatenates a few strings and renders them with DrawString?. Example:
DrawStringF("Creature % dealt %d damage", creatureName, damageValue) and the output is: Creature Giant dealt 4 damage.
I'm loading creatureNames and damage values from external csv files or generating them at runtime. I ported all my code before to Linux/Mac using standard C and I couldn't find any problems, so I guess it's down to how It converts. I'm looking for some help to nail a DrawString that can render in QuickDraw objects just like DrawString so I can just wrap up development.
Note: creatureName is of varied length. Can be Bat, Spider, HugeThingWithAReallyLongName. | Posted by: cheesestraws on 2022-09-06 07:27:15 Try something like this:
#include <stdarg.h>
#include <stdio.h>
void drawCStringf(char* fmt, ...) {
va_list aptr;
char buffer[257];
int clamped_size;
// do the printf gubbins
va_start(aptr, fmt);
clamped_size = vsnprintf(buffer + 1, 256, fmt, aptr);
va_end(aptr);
if (clamped_size > 255) {
clamped_size = 255;
}
buffer[0] = (char)clamped_size;
DrawString((unsigned char*)buffer);
}
This requires the C dialect your version of CodeWarrior is using to be modern enough to have the snprintf family of functions. They're present in CWPro 4. Also, yes, 257 is not a typo.
If it's not up-to-date enough to have snprintf and friends, I strongly suggest upgrading. They make working with strings in C nearly bearable. | Posted by: cheesestraws on 2022-09-06 08:38:31 Here's a better version. This one will work properly for strings > 128 chars. Guess why š
void drawCStringf(char* fmt, ...) {
va_list aptr;
unsigned char buffer[257];
int clamped_size;
// do the printf gubbins
va_start(aptr, fmt);
clamped_size = vsnprintf((char*)(buffer + 1), 256, fmt, aptr);
va_end(aptr);
if (clamped_size > 255) {
clamped_size = 255;
}
buffer[0] = (unsigned char)clamped_size;
DrawString(buffer);
} | Posted by: Crutch on 2022-09-06 12:13:43 Why donāt you just draw each string sequentially? DrawString automatically concatenates as it goes ā¦. (It doesnāt add a newline at the end)
void LogStr(Str255 s)
{
DrawString(s);
DrawChar(' ');
}
void LogNum(long n)
{
Str255 s;
NumToString(n, s);
LogStr(s);
}
...
Str255 name;
long dmg;
LogStr("\pCreature");
LogStr(name);
LogStr("\pdid");
LogNum(dmg);
LogStr(ā\pdamageā); | Posted by: cheesestraws on 2022-09-06 12:16:22
Why donāt you just draw each string sequentially? DrawString automatically concatenates as it goes ā¦.
Every time you reply to something I learn something. How did I not know about this? | Posted by: BacioiuC on 2022-09-06 12:23:54
Why donāt you just draw each string sequentially? DrawString automatically concatenates as it goes ā¦. (It doesnāt add a newline at the end)
void LogStr(Str255 s)
{
DrawString(s);
DrawChar(' ');
}
void LogNum(long n)
{
Str255 s;
NumToString(n, s);
LogStr(s);
}
...
Str255 name;
long dmg;
LogStr("\pCreature");
LogStr(name);
LogStr("\pdid");
LogNum(dmg);
LogStr(ā\pdamageā); Wait what? You can ⦠it continues where it left of? What? | Posted by: BacioiuC on 2022-09-06 15:06:18 So I got everything working, Crutch's suggestion was a godsent and simplified things a ton (my previous code was trying to count the number of characters, move the pen based on the character number, split strings and all that in order to position a draw string properly. Turns out, it continues where the previous one left of so goodbye to about 50 lines of code).
Now, for the issue I was bumping into before with my old code. In Code Warrior 4 gold C2PStr converts in place. I assumed it returned a pascal string to use with DrawString. What I was trying to Draw were strings loaded from a CSV files, at run time (so people can mod the game, add creatures, items, etc). The problem?
Creature names, attack names, items were converted in-place using C2PStr when calling it inside of DrawString and that kept causing a ton of issues. I thought it was due to me using strcat and strcpy badly somewhere.
So I ended up keeping things simple.
4 functions:
void BeginLog(int pos);
void AddToLog(Str255 logMessage);
void NumToLog(int num);
void EndLog( ); .
I needed a begin and end because I keep messing with the text color, back and front and I needed to revert the changes.
For the dynamic strings loaded at run time, since you can't actually do Str255 string = GetCreatureName(i) (which is a char* _entityList[id].name) I did the following to workaround the in-place conversion (@ Cheesey's suggestions).
char buffer[50];
strcpy(buffer, GetCreatureName(i));
AddToLog(C2PStr(buffer));
AddToLog("\pattacked you for");
NumToLog(damage);
AddToLog("\pDMG");
And that's basically it. No more issues.
Thanks Crutch and Cheesey for everything š
edit: also JCS basically has a vsnprintf working for Think-C here. I started porting the code to code warrior's syntax for quickdraw related stuff so fingers crossed. If you're using think-c you should be able to just use util.h and have access to the files directly. | Posted by: olePigeon on 2022-09-06 17:01:48 C Draw
C DrawString
StringDrawString | | 1 |
|