Converting Android game to PC

Started by
17 comments, last by Affected1 9 years, 5 months ago

So i have been working on this conversion for some time now and i got most of the code working but the problem is with android's canvas class. How could i possibly implement that in c++ using sdl?

Advertisement

You will have to write a wrapper for the canvas calss. That will be a class with the same interface that the android canvas has but internally is making draw calls to sdl instead.

My current game project Platform RPG

Do you have any advice on what calls to sdl need to be made in canvas functions like save() and restore() because those are the only problems im having now.

You won't find an exact counterpart for everything in SDL, you'll have to implement some things from scratch. I've never used the android Canvas' save and restore functions, but from the description on Android Developers it seems you need a stack (you can use an std::stack or write one yourself) to store copies of the current matrix of transformations and clip (if save and restore are the only problems you have, you should already have the matrix and clip somewhere). So, your wrapper would have that stack, the matrix and the clip as attributes and you'll use something like this:


void Wrapper::save() {
  //Make copies of matrix and clip, before creating the container or inside the constructor
  MatrixAndClipContainer* container = new MatrixAndClipContainer(this->matrix,this->clip);
  this->stack->push(container);
}

void Wrapper::save() {
  MatrixAndClipContainer* container = this->stack->pop();
  this->matrix = container->matrix;
  this->clip = container->clip;
}

MatrixAndClipContainer could be a private class or struct inside your Wrapper, or you could use 2 different stacks for matrices and clips.

If you need the other save and restore functions you need some more code, you'll need to emulate the use of different flags for the save methods and pop more than one time for the restoreToCount method.

I made these functions for save and restore. I also switched from sdl to sfml because sdl dint have some functions that were needed.


struct CanvasState {
	float x;
	float y;
	float rotation;
};

CanvasState cstate;
std::vector<CanvasState> stack;

void Canvas::save()
{
	cstate.x = x;
	cstate.y = y;
	cstate.rotation = rotation;
	stack.push_back(cstate);
}

void Canvas::restore()
{
	
	stack.pop_back();
}

cstate struct and stack vector are stored in private section of Canvas class. I think the save function works but i couldnt work out how to implement the restore function.

You need to replace canvas's x, y and rotation values, or am I missing something else?

One thing I noticed is you're using push_back and pop_back, you should check the stack class documentation: http://www.cplusplus.com/reference/stack/stack/

Use "push" to insert elements at the end

Use "pop" to remove the last element (it doesn't return the element)

Use "top" to access the last element (it doesn't remove the element)

So, your restore should look similar to this:


void Canvas::restore()
{
        cstate = stack.top();
        
        x = cstate.x;
        y = cstate.y;
        rotation = cstate.rotation;

        stack.pop_back();
}

EDIT: Edited the function a bit

So i'm pretty sure the restore and save functions are working now. But i got a new problem with the canvas class: when i draw a bitmap, i need to scale it to fit in a rectangle.

Here is my code so far:


void Canvas::Draw(sf::Sprite sprite, Rect *src, RectF dst)
{
	sprite.setScale(SCREENW/dst.width, SCREENH/dst.height);
	sprite.setPosition(cx, cy);
	sprite.setRotation(crotation);

	canvasTexture.draw(sprite);
}

It works for some bitmaps but with smaller ones it scales them way too big. The background image is 700x954 and that works fine but some other bitmap is 141x126 and it scales that way up when it should scale them down to fit the 'dst' rectangle. Any advice on this?

SCREENW, SCREENH, dst.width and dst.height are all ints, right? If you divide 2 ints you get an int as the result and will see some issues like that (you end up scalling by round value when you actually needed a fraction).

Use an extra step to copy dst.width and dst.height into temp float variables and then make the division with those, or cast them to float directly.

dst.width and dst.height are floats as RectF is rectangle class with all values as floats like in android RectF. I changed the scale code to:


sprite.setScale((float)SCREENW/dst.width, (float)SCREENH/dst.height);

but it still wrongly scales them too big. I'm thinking the problem is that this division is not how android does the scaling to fit the bitmap in the rectangle. I tried looking around in the android source code but its just too complex to find anything so specific.

Oh, OK, RectF is a rectangle with floats. Yes, casting SCREENW and SCREENH to floats won't make a difference in that case.

Can you give an example of what are you doing? Sprite is the bitmap, what is "src" and why are you sending one if you don't use it?

Print to the console the sizes of things and the result of the divisions, it might give you an idea of what's happening.

Just a guess here, but doing "SCREENW/dst.width" looks odd, shouldn't it be something like "src->width/dst.width" instead? or maybe use the sprite's width instead of SCREENW?

This topic is closed to new replies.

Advertisement