News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_EgoTrip

EgoTrip's Game Progress Topic

Started by EgoTrip, 22:45, 09 November 15

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

EgoTrip

In case anybody is interested here's a video of the progress I have made on my game:



The sprite doesn't disappear when playing without the video encoding. Don't know why its doing that. The sound is out of sync too for some reason. Don't know why I can't get it working properly, sometimes it does, most the time it doesn't.

I have changed the tilemaps from 8x8 using the tilemap functions to display them, to 16x16 using the sprite functions. This has freed up a bit of memory (each screen takes up 1/4 of the space). But there is now more memory used by the tiles. I have got sound fx working, music on the title screen (not shown as its not ready to be unveiled yet). I will need to figure out compression as there will not be enough memory for 64 screens, multiple enemy sprites and all the associated code and puzzles. I want the game to be run in 64K, on a bare bones 464.

There is a map top-right which shows where you are and where you have been. There are enemies coded but not used on this build. I will show them on the next preview.

There is a basic puzzle, you cannot go north without the torch. Well, you can, but you are likely to get very lost. So you find the torch, then you can go north, and collect the three jewels. The jewels reappear though. The torch does not, but its not optimal how I have done it. I need to figure out how to stop them reappearing then I can use the same routine for the torch (and other collectables).

I will keep updating this topic with progress.

ervin

It's looking really good.
Looks quite responsive and nippy.

If you need any help with compression, yell out.
I've used exomizer a *lot* over the last few years, and had great results with it.

Just confirming... you're using cpctelera?

||C|-|E||

It looks really cool! I will play it for sure if you finish it :)

Gryzor

Not a fan of this kind of games, but I'd lie if I said it doesn't look really pretty!

seanb

That looks extremely good.
Cannot wait to try it.
Thou shall not question Captain Wrong!

VincentGR


EgoTrip

Thanks for the comments.

@ervin yes I'm using CPCtelera. I've almost completely ran out of memory though. It was going way past 0xB000 and wouldn't load. I had to comment out a lot of stuff to make everything fit. Now It goes up to around 0xA300.  The map is 64x16x10 which equals 10240 bytes (0x2800). So, to free up memory I put it at 0x1000 (the audio resides at 0x3818) and for some reason, although it should fit, it keeps coming up with overwrite warnings when I compile. The title screen displays and the music plays (which is what I assume would have been overwritten),  but the game crashes when started.

I'm also having flicker problems with the main sprite. It's even more obvious on a real CPC.

Targhan

#7
There are many ways to optimize your map. One thing could be to load areas from the disk (mandatory for big games).
Also, instead of having a simple array for each room, you could:
- Specify one tile to fill the background.
- Have a list of positions for specific elements, such as the trees (stores the X/Y of each trees in a list).
- For more geometrical areas such as your dungeons, have little system of horizontal/vertical lines, storing only the origin, the direction, the length, and the tile to repeat.

With such system, a full room could be encoded in a few dozen of bytes.
Targhan/Arkos

Arkos Tracker 2.0.1 now released! - Follow the news on Twitter!
Disark - A cross-platform Z80 disassembler/source converter
FDC Tool 1.1 - Read Amsdos files without the system

Imperial Mahjong
Orion Prime

ervin

#8
You can disable the firmware, and also move the stack pointer, to get the maximum amount of free RAM.


#define NEW_STACK (void*)0xC000-64

cpct_disableFirmware();
cpct_setStackLocation(NEW_STACK);


I've put the stack 64 bytes below 0xC000, and I allow for 64 bytes movement up or down.
Therefore I'm allowing my program to use RAM all the way up to 0xC000-128 = 0xBF80.

That's a lot of extra RAM, and, as Targhan suggested above, there are many things that can be done to shrink your room definitions.

I wrote a tile-based scrolling engine a couple of years ago, and I didn't store all the tile references for a screen.
I simply stored the X/Y position of each object into a simple array.
Then each object has its own tile reference list.

This way, if you have 4 copies of an object on the screen, you simply have 4 sets of objectID,X,Y in the room definition (for that objectID).
Then when you are drawing the screen, you use the objectID to access a table of objects and their tile references.
It helps to think of it all as a database.

Also, exomizer.
8)

EgoTrip

@Targhan sounds complicated. I'm not very good at that sort of thing. Also due to the way the engine works, I don't think it will be suitable without a complete re-write. Its a miracle what I have done is working.

@ervin I already have firmware disabled but the problem is loading in something from BASIC that overwrites the part of the firmware that deals with loading.

arnoldemu

Quote from: EgoTrip on 13:59, 11 November 15
@Targhan sounds complicated. I'm not very good at that sort of thing. Also due to the way the engine works, I don't think it will be suitable without a complete re-write. Its a miracle what I have done is working.

@ervin I already have firmware disabled but the problem is loading in something from BASIC that overwrites the part of the firmware that deals with loading.
@EgoTrip: pm or e-mail me the source and I'll happily take a look and see what can be done. If I sort it out I'll explain what I did and why :)


If you're loading from BASIC and the file is too big there are two choices.
1. split it up. Load part into main ram, part into screen and in the loader join them together
2. load the data really low (e.g. 0x0040) and then copy into it's final location.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

arnoldemu

#11
Quote from: EgoTrip on 13:59, 11 November 15
@Targhan sounds complicated. I'm not very good at that sort of thing. Also due to the way the engine works, I don't think it will be suitable without a complete re-write. Its a miracle what I have done is working.

@ervin I already have firmware disabled but the problem is loading in something from BASIC that overwrites the part of the firmware that deals with loading.
@EgoTrip: you're doing great and result is good.

Targhan suggested a good simple method which is to make 1 map for each screen. You then store each of these screens on the disc as a seperate file. Now in your code you need to know, if you move to the left, right, up or down, which screen is next to load.
Then when you do that movement, load the screen and display it. The code has space for 1 screen at a time and you load each new one into this area.

The easiest thing is to keep firmware active so that you can load the screens using the firmware disc routines.
I am not sure how easy it is to manage separate files with cpctelera.

EDIT: The complication here is anything that can be picked up/dropped, or any obstacle/puzzle that must be completed.
In this case you need to remember the location of each item seperately from the files for the screens. You must also remember which puzzles you completed.

But then again you need to remember this if the game is re-started? So this data should be stored seperately.
e.g. jewel, x,y, screen, collected?



@ronaldo: Does cpctelera allow management of separate files?
@ronaldo: Does cpctelera allow you to define a loader program which can load seperate parts and join them if necessary?

My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

reidrac

#12
Quote from: arnoldemu on 14:36, 11 November 15
@EgoTrip: you're doing great and result is good.

Targhan suggested a good simple method which is to make 1 map for each screen. You then store each of these screens on the disc as a seperate file. Now in your code you need to know, if you move to the left, right, up or down, which screen is next to load.
Then when you do that movement, load the screen and display it. The code has space for 1 screen at a time and you load each new one into this area.

The easiest thing is to keep firmware active so that you can load the screens using the firmware disc routines.
I am not sure how easy it is to manage separate files with cpctelera.

EDIT: The complication here is anything that can be picked up/dropped, or any obstacle/puzzle that must be completed.
In this case you need to remember the location of each item seperately from the files for the screens. You must also remember which puzzles you completed.

But then again you need to remember this if the game is re-started? So this data should be stored seperately.
e.g. jewel, x,y, screen, collected?

There are other ways to deal with this without using disk.

For example, if a screen is 16x10 (and you have 64 screens, if I understand correctly what @EgoTrip said), then you can have 160 bytes to put the working screen and compress each screen individually. Then when you change screen, you uncompress into those 160 bytes (that's what Space Pest Control does, each screen is 100 bytes that is compressed to ~60% of that).

Also you could define the screens in a more smarter way (as other mentioned already) so they use less memory.

Then your problem is remembering state (object x was collected). Well, that's easy! If you identify each object with one unique ID (say 1 byte), you only need an array as large as the number of objects.

In Space Pest Control I can handle 8 persistent objects per screen, meaning that I can save that information with just 1 byte per screen ;)

I know  it sounds like adding limitations to your design, but that's about it when you're dealing with very low resources.

EDIT: sorry, the persistence part could be more complicated than that, it all depends how you currently store your data. I just hope this may give you ideas!
Released The Return of Traxtor, Golden Tail, Magica, The Dawn of Kernel, Kitsune`s Curse, Brick Rick, Hyperdrive and The Heart of Salamanderland for the CPC.

If you like my games and want to show some appreciation, you can always buy me a coffee.

Targhan

What I proposed is not complicated at all, don't worry, and I'm pretty sure you HAVE to do something like that, else you won't be able to finish your game.
What I talked about is just how to encode each room in a specific, compressed format. When you enter the room, you decompress it into an uncompressed array composed of raw tiles, your engine already work with. So nothing changes in your engine: only a small work to do when entering a room.
Targhan/Arkos

Arkos Tracker 2.0.1 now released! - Follow the news on Twitter!
Disark - A cross-platform Z80 disassembler/source converter
FDC Tool 1.1 - Read Amsdos files without the system

Imperial Mahjong
Orion Prime

sigh

Great work and looking good!

Out of interest, was this idea originally planned to be created with Arcade Game Designer on the CPC?

EgoTrip

Quote from: sigh on 20:35, 11 November 15
Great work and looking good!

Out of interest, was this idea originally planned to be created with Arcade Game Designer on the CPC?

Sort of. I did a limited prototype version of the game for the Spectrum in AGD: New Game: A Prelude to Chaos - World of Spectrum But I had problems porting it over to the CPC version due to bugs in AGD. It is also missing quite a few things I want to include that AGD is too limited for. Besides, I always wanted the game to be in MODE 1. AGD only does MODE 0.

arnoldemu

@EgoTrip: I have looked at the source.

First in the config file set the start to 0x0040.
This is the lowest that is ok.

Z80CODELOC := 0x0040

Then I removed all the __at to put all the data together.

I built and it came to 25K.
code ends around 6B00. You have another 15K to go :)

When you reach that limit there is more that can be done. :)

My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

EgoTrip

What about the music? That has to be where it was located or it wont work. I could always recompile the bin files but its hard to know where it will reside in memory so its easier to put it below &4000. Also according to the documentation, some routines can't be used below &4000 which is why I started the code there.

ervin

Quote from: EgoTrip on 23:26, 11 November 15
What about the music? That has to be where it was located or it wont work. I could always recompile the bin files but its hard to know where it will reside in memory so its easier to put it below &4000. Also according to the documentation, some routines can't be used below &4000 which is why I started the code there.

In RUNCPC, I had all my data located below 0x4000 (music, exomized sprites, lookup tables etc), and all my code above 0x4000.
It worked great.

arnoldemu

Quote from: EgoTrip on 23:26, 11 November 15
What about the music? That has to be where it was located or it wont work. I could always recompile the bin files but its hard to know where it will reside in memory so its easier to put it below &4000. Also according to the documentation, some routines can't be used below &4000 which is why I started the code there.
good point.

I'll re-arrange it tonight and get back to you.
I'm going to do as ervin suggests and locate all of the data below &4000.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

EgoTrip

So how do I get the data below 0x4000 without "overlap record detected" errors showing up and the game being corrupted?

TFM

Maybe you can load a binary there?
TFM of FutureSoft
Also visit the CPC and Plus users favorite OS: FutureOS - The Revolution on CPC6128 and 6128Plus

arnoldemu

I found a way but it's not cpctelera compatible. So I need ronaldo's help.

There are two things that can be done:

- Set the location of the run time data (_DATA section in cpctelera/sdcc speak). Yours is small so doesn't make much difference. This can't be defined in cpctelera.

- Use the following at the top of each c file to control where the data goes.
Replace CONSTDAT with a short (8 letter max) name.

#pragma constseg CONSTDAT

- in C there are "sections". These contain data and/or code. You can use the #pragma to name a section. The purpose of sections is to organise. You can then define where in memory the section begins. All c files with the same section are grouped together. Normally there is _CODE and _DATA. and data is put after _CODE. There are others, but ignore them they are not important here.

In my separate linker script I have this (cpctelera doesn't use linker scripts):

-b _CONSTDAT=0x0040

That moves all the data defined with const u8.

You can still have your music located at the absolute location. :)

To manage this you will need to move data from one file to another to split them up and control which section they are grouped in.

To avoid the error, look at the .map file. In the obj directory.

it looks like this:

  00000000  s__DABS                         
     00000040  s__CONSTDAT                       
     00000047  l__INITIALIZED                 
     00000047  l__INITIALIZER                 
     000000CF  l__DATA                         
     0000293C  l__CODE                         
     00003EC0  l__CONSTDAT                   
     00004000  s__CODE                         
     0000693C  s__DATA                         
     00006A0B  s__INITIALIZED                 
     00006A52  s__GSFINAL                     
     00006A52  s__GSINIT                       
     00006A52  s__HOME                         
     00006A52  s__INITIALIZER

The s__ prefix is the *start*. The l__ prefix is the length. From this you can know how long each section is, where it starts and then you

In this s__CODE is start of code "section".

I will talk with ronaldo about the best way to make this easy for users to control.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

ervin

You can tell cpctelera precisely where to put data.

In RUNCPC, I have the following DEFINEs in define.h:


#define ADDR_FRAME_BUFFER 0x0100
#define ADDR_SCREEN_BUFFER 0x0500
#define ADDR_BACK_BUFFER 0x0900

#define ADDR_AUDIO 0x0d00 // 256
#define ADDR_SPRITE 0x0e00 // 5888 (allow for 5667+140=5807)
#define ADDR_T_SIZE 0x2500 // 128
#define ADDR_G_PALETTE 0x2580 // 16
#define ADDR_TILEBANK 0x2590 // 512
#define ADDR_EXO_BUFFER 0x2790 // 0x4f20-0x2790=10128


Then I have another file called global.h.
It contains things like:


__at(ADDR_FRAME_BUFFER) u8 FRAME_BUFFER[1024];
__at(ADDR_SCREEN_BUFFER) u8 SCREEN_BUFFER[1024];
__at(ADDR_BACK_BUFFER) u8 BACK_BUFFER[1024];
__at(ADDR_AUDIO) u8 AUDIO_BUFFER[1280];
__at(ADDR_SPRITE) u8 SPRITE_BUFFER[5888];

__at(ADDR_G_PALETTE) u8 const g_palette[16]={
    0x00, // black
    0x01, // blue
    0x02, // brightBlue
    0x03, // red
    0x04, // magenta
    0x05, // mauve
    0x06, // brightRed
    0x09, // green
    0x0b, // skyBlue
    0x0d, // white
    0x0f, // orange
    0x12, // brightGreen
    0x18, // brightYellow
    0x1a, // brightWhite
    0x07, // purple
    0x0c, // yellow
};


arnoldemu

@ervin: Yes you can. That requires exact knowledge of the length of the data and is hard to maintain if it changes size.

I know that EgoTrip already uses this to set the location of the music.

But I think for const data it would be great if cpctelera allowed you to locate it where you want and you can set it and forget it (well almost as easy as that ;) ).
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

Powered by SMFPacks Menu Editor Mod