Page 1 of 4

Project - Mega Dracula - Help / Updates

Posted: Tue Sep 01, 2015 9:12 am
by matteus
It was bound to happen eventually :) I'm writing a game! It's going to be pretty basic but I'm going to post my progress and need for help here! My experiment with animation may even come in handy with this project!

I'm having to get back into the swing of writing purely in C rather than C#.

First stumbling block, I'm not sure how to strcat strings in C!

Code: Select all

                // add string item to ling string
                strcat(lineStr, " " & tempStr);
Okay so I fixed the problem in this instance I need to call strcat twice! Once for the space and then once again to add the number

Code: Select all

                strcat(lineStr, " ");
                strcat(lineStr, tempStr);

Re: Project - Mega Space Heist - Help / Updates

Posted: Tue Sep 01, 2015 10:23 am
by matteus
Strings are really driving me nuts! The following function is flagging me with the error:

incompatible types in assignment

I'm confused surely a 1 character char should be assigned the character s without an issue?

Code: Select all

static char mapItemLookup(u16 P)
{
    char returnStr[1] = "";
    switch (P)
    {
        case 143 :
            returnStr = "s";
            break;
        case 90 :
            returnStr = "z";
            break;
        case 71 :
            returnStr = "g";
            break;
        case 68 :
            returnStr = "d";
            break;
        case 63 :
            returnStr = "?";
            break;
        case 61 :
            returnStr = "\061";
            break;
        case 42 :
            returnStr = "\042";
            break;
        case 45 :
            returnStr = "\095";
            break;
        case 43 :
            returnStr = "\043";
            break;
        default :
            returnStr = "0";
    }
    return returnStr;
}

Re: Project - Mega Space Heist - Help / Updates

Posted: Tue Sep 01, 2015 10:58 am
by djcouchycouch
It's because you've got them double quotes (") which means it's a string (char*) and not a single character. You need to put them in single quotes (') for single characters.

Re: Project - Mega Space Heist - Help / Updates

Posted: Tue Sep 01, 2015 3:11 pm
by matteus
Thanks Couchy! I've another one you might be able to help me with!

I'm not great with the whole concept of writing to the screen on every refresh. I've got this code structure so far:

Code: Select all

    while(TRUE)
    {
    
        handleInput();
        
        if (stage == 0) {
            VDP_drawText("Hello......", 1, 10);
        } else if (stage == 1) {
            VDP_resetScreen();
            stage = 2;
        } else if (stage == 2) {
             VDP_drawText("How are you?", 1, 10);
        } 
        
    }

static void handleInput()
{
    u16 value = JOY_readJoypad(JOY_1);

    if (value & BUTTON_START) {
            stage++;
    }

}
The problem is because the start button is so sensitive to being held down my stage increment jumps the gun too quickly and I end up with stage==6 or stage==7 with one press. How do you get around this sort of thing?

Re: Project - Mega Dracula - Help / Updates

Posted: Tue Sep 01, 2015 5:59 pm
by djcouchycouch
I think it's because JOY_readJoypad just returns the state of the button, pressed or not pressed. The code checks whether it's pressed, increments the stage variable but when it comes back on the next frame, sees that it's still pressed and does the work again. It'll do it as long as the button is held down.

What you need is to know when the button was released. To know if the button was released, you need to check what the state of the button was on the previous frame. If the button was pressed on the previous frame and not pressed on the current frame, that means the button was released and you can increment stage.

so something like:

Code: Select all

// this is somewhere
u16 lastStartState = 0;

static void handleInput()
{
    u16 value = JOY_readJoypad(JOY_1);

    u16 currentStartState = value & BUTTON_START;

    if (lastStartState && !currentStartStage) { // lastStartState is 1 and currentStartState is 0
            stage++;
    }

    lastStartState = currentStartState;

}

You can also generalize the "last state" stuff so that it handles all the buttons, to figure out if a button was just pressed or just released, etc.

Re: Project - Mega Dracula - Help / Updates

Posted: Tue Sep 01, 2015 6:15 pm
by tryphon
Personnally, I make something like that:

Code: Select all

u16 joy_value;
u16 joy_change;

void handle_input() {
    u16 old_value = joy_value;
    joy_value = JOY_readJoypad(JOY_1);

    joy_change = ~old_value & joy_value;
}
This way joy_change contains states of all buttons that were just "clicked". You can access to a particular button the same way you do with joy_value.

Re: Project - Mega Dracula - Help / Updates

Posted: Tue Sep 01, 2015 8:14 pm
by matteus
Thank you guys! You've sorted my problem, I'm about 25% through the build :) Should have something to show very shortly! I want to try and get a pixel artist helping me first though!

Re: Project - Mega Dracula - Help / Updates

Posted: Tue Sep 01, 2015 8:18 pm
by matteus
Does anyone know how to access the window plan?

Re: Project - Mega Dracula - Help / Updates

Posted: Tue Sep 01, 2015 11:02 pm
by KanedaFr
For joy handling, I suggest to use Joy_eventHandler

ex: https://bitbucket.org/SpritesMind/genre ... trols.c-72

A lot more useful since handler is only called on change and you already have the changed and current joy status

Re: Project - Mega Dracula - Help / Updates

Posted: Wed Sep 02, 2015 9:34 am
by matteus
To calculate when you can't go beyond a wall I use the following code:

I'm not sure how to deal with this one in C as it uses decimal places and the BASIC I ported it from rounds down rather than up!

Pseudo code

Code: Select all

if (((PositionInt - 1) / 20) == round(((PositionInt - 1) / 20))) { RT = 1; }
Position = 20
0.95 == 0

Position = 21
1 == 1

Re: Project - Mega Dracula - Help / Updates

Posted: Wed Sep 02, 2015 2:31 pm
by djcouchycouch
It's not clear to me how you're representing your walls. Are you working with a tilemap for level collisions?

Re: Project - Mega Dracula - Help / Updates

Posted: Wed Sep 02, 2015 3:28 pm
by matteus
Sorry I'll explain in more detail it's a dungeon crawler!

I have a [22][17] array, rows are 20 spaces long with walls found at each end

19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00

So if I was in space 19 and wanted to go WEST, I'd be moving to position + 1 and that is where this code kicks in to check!

A = (19+1)/20
B = Round((19+1)/20)

Which means A == B (1 == 1) meaning I can't move

If we did the same with place 18

A = (18+1)/20
B = RoundDown(18+1)/20

A == B (0.95 == 0) meaning I can move

Re: Project - Mega Dracula - Help / Updates

Posted: Wed Sep 02, 2015 4:04 pm
by tryphon
Why don't you just test if A == 0 or A == 20 ?

Re: Project - Mega Dracula - Help / Updates

Posted: Wed Sep 02, 2015 4:15 pm
by matteus
Because when you go up a row the maths changes :)

ROW 1: 39 38 37 36 35 34 33 32 31 20 29 28 27 26 25 24 23 22 21 20
ROW 0 : 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00

Re: Project - Mega Dracula - Help / Updates

Posted: Wed Sep 02, 2015 5:07 pm
by tryphon
Fast answer : modulo. I'll elaborate later.

Edit: So, what you want to know is :
does A equal to 0, 20, 40, 60, etc. ? , i.e. is A a multiple of 20 ?

The modulo of A and 20 (denoted A % 20 in Python, and IIRC in C too) is the remainder in the (euclidean, or integer) division of A by 20.
For example, 68 / 20 = 3, and the remainder is 68 - 20*3 = 8, so 68 % 20 = 8.

To state that A is a multiple of 20 is the same as stating that A % 20 = 0.

So your test should be :

Code: Select all

if (A % 20 == 0) || ((A + 1) % 20 == 0)
Or even better (because you compute only one modulo) :

Code: Select all

B = A % 20;
if ((B == 0) || (B == 19))
That said, computing a modulo is like computing a division : it's slow. Except in case the right term is a power of 2. In this case, the modulo is given by the right-most bits. For example, computing modulo 2^5 = 32 is the same as keeping the 5 right-mosts bits, so A % 32 is the same as A & 0x1F.

So you should make your rows 32 bytes long (by padding) and your test should be :

Code: Select all

B = A & 0x1F;
if ('B == 0) || (B == 19))