Author Topic: WinCPCTelera  (Read 9161 times)

0 Members and 1 Guest are viewing this topic.

Offline Arnaud

  • Supporter
  • 6128 Plus
  • *
  • Posts: 506
  • Country: fr
  • Liked: 418
  • Likes Given: 796
Re: WinCPCTelera
« Reply #75 on: 10:24, 16 June 19 »
Hi  @awergh,
thanks for reporting.

I just check my code for missing key in WinCPCTelera and all is (fortunately) OK.

;D Edit :
Effectively there is a problem, enum are stored in C in int and cpct_keyID is unsigned short.

Code: [Select]
int enumKeyZ= (i16)0x8008; -> 0xFFFF8008;
cpct_keyID  myKeyZ = getKey(); -> 0x8008;

PROBLEM : enumKeyZ != myKeyZ

I work on it.


By the way here the version of getKey() i used in my games :

Code: [Select]
cpct_keyID getKey()
{
/** From Ronaldo in cpcwiki forum */
u8* keyStatus = cpct_keyboardStatusBuffer;
u8 i;

while (!cpct_isAnyKeyPressed());

for (i = 0; i < 10; i++)
{
cpct_keyID keypressed = *keyStatus++ ^ 0xFF;
if (keypressed)
return (keypressed << 8) + i;
}

return 0;
}


Have you completed your changes for CPCtelera 1.5?
I haven't decided if I should be using 1.4.2 or grabbing the latest 1.5 from github.

You can use WinCPCtelera with 1.5, i have migrated my projects to this version and i'm currently programming with it.

I haven't yet migrated String functions but i'll do it today (i saw you use them).

« Last Edit: 11:00, 16 June 19 by Arnaud »

Offline awergh

  • CPC6128
  • ****
  • Posts: 209
  • Country: au
  • Liked: 67
  • Likes Given: 167
Re: WinCPCTelera
« Reply #76 on: 12:00, 16 June 19 »
Thanks for that I'll have a look once I start programming.
I decided to have some discipline this year and try to do much of my planning this month before getting into the development in July as per usual.


I wouldn't be too worried to rush with the String functions, I used them in my 2016/2017 entries and little things but I expect I will use a custom font (same as 2018) as it made memory management below 0x4000 much easier.


I think I'm convinced to go for 1.5 I'll just note which revision it is and stick to it.
I do like the idea that someone could compile my code easily if they wanted to even though there isn't much reason to do so.

Offline Arnaud

  • Supporter
  • 6128 Plus
  • *
  • Posts: 506
  • Country: fr
  • Liked: 418
  • Likes Given: 796
Re: WinCPCTelera
« Reply #77 on: 13:11, 16 June 19 »
Corrections pushed :
- Solve incompatibility between cpct_keyId enum and typedef
- Update String functions for cpctelera 1.5 API
- Correction in String functions (wrong character could be displayed and mode 2 Space character was not drawn)
- Minor corrections

Thanks a lot for reporting @awergh  :)



Offline awergh

  • CPC6128
  • ****
  • Posts: 209
  • Country: au
  • Liked: 67
  • Likes Given: 167
Re: WinCPCTelera
« Reply #78 on: 09:50, 20 July 19 »
I found another bug in wincpctelera.  ;D
I was trying out bitarrays for the first time and found that some elements in the arrays were not set to valid values.
So in my example below it is supposed to show a graphic in each screen position but some spots are blank.

Also I noticed that when I was trying to use cpct_drawStringM0 it didn't display anything at all! (so I used graphics for this example instead)

Code: [Select]
#include <cpctelera.h>
#include <stdio.h>


#define SCREEN_TILES_Y 12
#define SCREEN_TILES_X 20
#define TILE_HEIGHT 16
#define TILE_WIDTH_BYTES 4


const u8 xPositions[20] = { 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76 };
const u8 yPositions[12] = { 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176 };


const u8 G_magnifying_glass[64] = {
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x88, 0x00, 0x00,
    0x44, 0xCC, 0x00, 0x00,
    0x44, 0xCC, 0x00, 0x00,
    0x44, 0xCC, 0x00, 0x00,
    0x44, 0xCC, 0x00, 0x00,
    0x44, 0xCC, 0x00, 0x00,
    0x00, 0x88, 0x80, 0x00,
    0x00, 0x00, 0x80, 0x00,
    0x00, 0x00, 0x40, 0x00,
    0x00, 0x00, 0x40, 0x00,
    0x00, 0x00, 0x00, 0x80,
    0x00, 0x00, 0x00, 0x80,
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00 };


void main(void)
{
    u8 i = 0;
    u8 x = 0;
    u8 y = 0;
    u8* mapMemory;
    u8 position = 0;


    //declare a bitarray
    CPCT_6BITARRAY(mapCells, 240);


    //disable the firmware to prevent it from interfering with setVideoMode
    cpct_disableFirmware();


    //set video mode to mode 0
    cpct_setVideoMode(0);


    //clear the screen
    cpct_clearScreen(0);


    //fill the bit array with values
    for (i = 0; i < 240; ++i)
    {
        cpct_set6Bits(mapCells, 0x11, i);
    }   


    //position is the element in the map tile array
    for (x = 0; x < SCREEN_TILES_X; ++x)
    {
        for (y = 0; y < SCREEN_TILES_Y; ++y)
        {
            u8 cellValue = cpct_get6Bits(mapCells, position);
            mapMemory = cpct_getScreenPtr(CPCT_VMEM_START, xPositions[x], yPositions[y]);


            if (cellValue)
            {
                //cpct_drawStringM0("a", mapMemory);
                cpct_drawSprite(G_magnifying_glass, mapMemory, TILE_WIDTH_BYTES, TILE_HEIGHT);
            }


            ++position;
        }
    }
   
    while (1);
}


« Last Edit: 09:58, 20 July 19 by awergh »

Offline Arnaud

  • Supporter
  • 6128 Plus
  • *
  • Posts: 506
  • Country: fr
  • Liked: 418
  • Likes Given: 796
Re: WinCPCTelera
« Reply #79 on: 23:41, 21 July 19 »
Hello @awergh,
i just uploaded my fix.

To sum up :
- Values of background and pen for the functions cpct_drawString were not initialized and set to 0 (pen must be set to 1)
- Wrong computation of bit position in byte

Thanks for testing.

Offline awergh

  • CPC6128
  • ****
  • Posts: 209
  • Country: au
  • Liked: 67
  • Likes Given: 167
Re: WinCPCTelera
« Reply #80 on: 15:27, 04 August 19 »
Hi @Arnaud
thanks for fixing it but I broke it again  :P
I might not actually end up using bit arrays in my game but I figure you would want it to work without bugs.

Code: [Select]

#include <cpctelera.h>
#include <stdio.h>


#define SCREEN_TILES_Y 12
#define SCREEN_TILES_X 20
#define TILE_HEIGHT 16
#define TILE_WIDTH_BYTES 4


const u8 xPositions[20] = { 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76 };
const u8 yPositions[12] = { 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176 };


const u8 G_magnifying_glass[64] = {
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x88, 0x00, 0x00,
    0x44, 0xCC, 0x00, 0x00,
    0x44, 0xCC, 0x00, 0x00,
    0x44, 0xCC, 0x00, 0x00,
    0x44, 0xCC, 0x00, 0x00,
    0x44, 0xCC, 0x00, 0x00,
    0x00, 0x88, 0x80, 0x00,
    0x00, 0x00, 0x80, 0x00,
    0x00, 0x00, 0x40, 0x00,
    0x00, 0x00, 0x40, 0x00,
    0x00, 0x00, 0x00, 0x80,
    0x00, 0x00, 0x00, 0x80,
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00 };


void main(void)
{
    u8 i = 0;
    u8 x = 0;
    u8 y = 0;
    u8* mapMemory;
    u8 position = 0;


    //declare a bitarray
    CPCT_6BITARRAY(mapCells, 240);


    //disable the firmware to prevent it from interfering with setVideoMode
    cpct_disableFirmware();


    //set video mode to mode 0
    cpct_setVideoMode(0);


    //clear the screen
    cpct_clearScreen(0);


    //fill the bit array with values
    for (i = 0; i < 240; ++i)
    {
        if (i % 3 == 0)
        {
            cpct_set6Bits(mapCells, 0x10, i);
        }
        else if (i % 3 == 1)
        {
            cpct_set6Bits(mapCells, 0x20, i);
        }
        else
        {
            cpct_set6Bits(mapCells, 0x01, i);
        }       
    }   


    //position is the element in the map tile array
    for (x = 0; x < SCREEN_TILES_X; ++x)
    {
        for (y = 0; y < SCREEN_TILES_Y; ++y)
        {
            u8 cellValue = cpct_get6Bits(mapCells, position);
            mapMemory = cpct_getScreenPtr(CPCT_VMEM_START, xPositions[x], yPositions[y]);


            if (cellValue & 0x10)
            {
                cpct_drawStringM0("c", mapMemory);
            }
            else if (cellValue & 0x20)
            {
                cpct_drawStringM0("b", mapMemory);
            }
            else if (cellValue) //blanks do not get drawn
            {
                cpct_drawStringM0("a", mapMemory);
            }


            ++position;
        }
    }
   
    while (1);
}
« Last Edit: 15:44, 04 August 19 by awergh »

Offline johnlobo

  • CPC464
  • **
  • Posts: 16
  • Country: es
  • Liked: 9
  • Likes Given: 10
Re: WinCPCTelera
« Reply #81 on: 14:47, 13 August 19 »

Hi,


I'm trying to give a test to WinCpcTelera, but I'm quite new with Visual Studio, and I'm not been able to do it.


First, I clone the WinCpcTelera repository, and when I open the solution in Visual Studio, it asks me for confirmation to retarget the project to windows SDK 10 and Toolbox 142. I've tried to skip thsi step, and not to retarget it, but the project doesn't build... so, I confirm, it retargets, and after retargeting, apparently the project is built with no further problem.


Then, I create a new project for testing, the tipical "Welcome to CpcTelera" message. And to make it work, I change the properties of the project so that WinCpcTelera resources can be located during the build process...


Include wincpctelera dir in  VC++ Directories/Include directories
Include wincpctelera\Visual\x64\Debug\ dir in C++ Directories/Library directories
And include "WinCpcTelera.lib" in Linker/Input/Addcitional dependencies
After all this, I try to build the test... but it doesn't work. Below is part of the output of the build process..


1>main.obj : error LNK2019: unresolved external symbol _cpct_setDrawCharM1 referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol _cpct_drawStringM1 referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol _cpct_getScreenPtr referenced in function _main
1>\source\repos\wincpctelera\Visual\x64\Debug\WinCPCTelera.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'x86'
1>
1>Unused libraries:
1>  \source\repos\wincpctelera\Visual\x64\Debug\WinCPCTelera.lib


From this ouptput I presume that the include configuration has worked (no compiler errors), and the library configuration has worked too, because WinCpcTelera.lib, appears as an unused library, but for some reason, the linker can't find the cpctelera functions in the library.


Besides there is this weird warning about the library machine and the target machine...  :-S


What am I doing wrong?? Any help would be appreciated.


Thanks.


Offline Arnaud

  • Supporter
  • 6128 Plus
  • *
  • Posts: 506
  • Country: fr
  • Liked: 418
  • Likes Given: 796
Re: WinCPCTelera
« Reply #82 on: 15:16, 13 August 19 »
Hi @johnlobo,
here my VS configuration from a project (in screenshot)

To sum-up my conf:
- Wincpctelera is a project static library
- Wincpctelera is a dependance of the main project
- The project is a Win32 application
- The path to the Wincpctelera headers must be set in main project.

Arnaud

Offline awergh

  • CPC6128
  • ****
  • Posts: 209
  • Country: au
  • Liked: 67
  • Likes Given: 167
Re: WinCPCTelera
« Reply #83 on: 16:55, 13 August 19 »

Just to add my thoughts as well to what Arnaud said.


I assume you are using a recent version of Visual Studio (I've used 2015-2019 with wincpctelera without issues).
Make sure you build both wincpctelera and your game in Win32 (x86) debug. (x64 and or release have not worked for me)


Offline johnlobo

  • CPC464
  • **
  • Posts: 16
  • Country: es
  • Liked: 9
  • Likes Given: 10
Re: WinCPCTelera
« Reply #84 on: 16:22, 14 August 19 »
Thank you both for the prompt response.


I've made some progress but it is not working yet... :-(


- I've following Arnaud instructions, and everything seem to work fine, but if I don't include Wincpctelera as a reference for the main project, I still get the unresolve external symbol error.
- After including Wincpctelera as a reference, everything seems to build fine, but when executed, it just shows an empty console window (see screenshot).


- I've tested it in VS 2017 & VS 2019 with the same results.


The process I follow is pretty simple


1) download Wincpctelera
2) create an empty project and add "main.c" file
3) add Wincpctelera to the test project solution
5) retarget Wincpctelera project to user newer windows SDK
6) add Wincpctelera as a reference of the test project
7) set Wincpctelera dir as additional include dir for the test project
8 ) build and execute the test project (wincpctelera is also built during the process).


The result of this process is an empty console window


Offline Arnaud

  • Supporter
  • 6128 Plus
  • *
  • Posts: 506
  • Country: fr
  • Liked: 418
  • Likes Given: 796
Re: WinCPCTelera
« Reply #85 on: 17:12, 14 August 19 »
Obviously there is a problem in the Window application creation.

Try to put a break point here :

Code: [Select]
winGDI.c

void wincpct_createWindowApp()

To see why the Window is not visible.

Offline johnlobo

  • CPC464
  • **
  • Posts: 16
  • Country: es
  • Liked: 9
  • Likes Given: 10
Re: WinCPCTelera
« Reply #86 on: 02:25, 16 August 19 »
Well, I don't know exactily what I did, because I've tried different combination of changes in the configuration of the solution, but at the end it works.Thank you very much for your help.
Now that I'm able to execute cpctelera code, I've notice some differences between what it's shown in wincpctelera and winape in some of the tests.
This is the code of the first test...

Code: [Select]
#include <cpctelera.h>

#define BG_COLOR 0

void drawWindow(u8 x, u8 y, u8 width, u8 height, u8 fgColor, u8 bgColor)
{
    u8 *pvideo;


    // top and bottom fgColor horizontal lines
    pvideo = cpct_getScreenPtr(CPCT_VMEM_START, x + 1, y);
    cpct_drawSolidBox(pvideo, cpct_px2byteM0(fgColor, fgColor), width - 4, 2);
    pvideo = cpct_getScreenPtr(CPCT_VMEM_START, x + 1, y + height);
    cpct_drawSolidBox(pvideo, cpct_px2byteM0(fgColor, fgColor), width - 4, 2);
    // top and bottom BG_COLOR horizontal lines
    pvideo = cpct_getScreenPtr(CPCT_VMEM_START, x + 1, y + 2);
    cpct_drawSolidBox(pvideo, cpct_px2byteM0(BG_COLOR, BG_COLOR), width - 4, 2);
    pvideo = cpct_getScreenPtr(CPCT_VMEM_START, x + 1, y + height - 2);
    cpct_drawSolidBox(pvideo, cpct_px2byteM0(BG_COLOR, BG_COLOR), width - 4, 2);
    // Internal box
    pvideo = cpct_getScreenPtr(CPCT_VMEM_START, x + 1, y + 4);
    cpct_drawSolidBox(pvideo, cpct_px2byteM0(bgColor, bgColor), width - 4, height - 6);

    // top left corner
    pvideo = cpct_getScreenPtr(CPCT_VMEM_START, x, y + 2);
    cpct_drawSolidBox(pvideo, cpct_px2byteM0(BG_COLOR, fgColor), 1, 2);

    // left vertical line
    pvideo = cpct_getScreenPtr(CPCT_VMEM_START, x, y + 4);
    cpct_drawSolidBox(pvideo, cpct_px2byteM0(fgColor, BG_COLOR), 1, height - 6);

    //bottom left corner
    pvideo = cpct_getScreenPtr(CPCT_VMEM_START, x, y + height - 2);
    cpct_drawSolidBox(pvideo, cpct_px2byteM0(BG_COLOR, fgColor), 1, 2);
    // top right corner
    pvideo = cpct_getScreenPtr(CPCT_VMEM_START, x + width - 3, y + 2);
    cpct_drawSolidBox(pvideo, cpct_px2byteM0(fgColor, BG_COLOR), 1, 2);
    // right vertical line
    pvideo = cpct_getScreenPtr(CPCT_VMEM_START, x + width - 3, y + 4);
    cpct_drawSolidBox(pvideo, cpct_px2byteM0(BG_COLOR, fgColor), 1, height - 6);
    // bottom right corner
    pvideo = cpct_getScreenPtr(CPCT_VMEM_START, x + width - 3, y + height - 2);
    cpct_drawSolidBox(pvideo, cpct_px2byteM0(fgColor, BG_COLOR), 1, 2);
}

void main(void) {

    cpct_disableFirmware();

    cpct_setVideoMode(0);

    drawWindow(3, 95, 21, 80, 1, 2);

    // Loop forever
    while (1);
}
And the result of both enpoints is in the snapshot attached.
Apparently the differece is related to the coordinates of the function cpct_drawSolidBox.

Offline Arnaud

  • Supporter
  • 6128 Plus
  • *
  • Posts: 506
  • Country: fr
  • Liked: 418
  • Likes Given: 796
Re: WinCPCTelera
« Reply #87 on: 10:08, 16 August 19 »
Hi @johnlobo,
it's nice that Wincpctelera finally works with you ;)

Thank for reporting,
the bug is solve (the two Bytes of cpct_px2byteM0 were inverted).

You can download the corrected file cpct_sprites.c directly on git.

I'am also working to correct the BitArray but it's not obvious.

Offline johnlobo

  • CPC464
  • **
  • Posts: 16
  • Country: es
  • Liked: 9
  • Likes Given: 10
Re: WinCPCTelera
« Reply #88 on: 12:49, 16 August 19 »
Hi Arnaud,


Could it be possible to have in WinCPCTelera "cpct_waitHalts"??. This function is in the developer branch, and it's basically a delay function.


Code: [Select]

cpct_waitHalts
Waits for a given number of halt assembler instructions to be executed.


C Definition
void cpct_waitHalts (u8 n) __z88dk_fastcall;


Input Parameters (1 Byte)
(1B B) n Number of halts to wait


As a workaround for my project I have included a define in the helper to call wincpct_wait, but it's not accurate.




Offline Arnaud

  • Supporter
  • 6128 Plus
  • *
  • Posts: 506
  • Country: fr
  • Liked: 418
  • Likes Given: 796
Re: WinCPCTelera
« Reply #89 on: 14:00, 16 August 19 »
Hi,
cpct_waitHalts added and tested.

Can you confirm it works also for your code ?


Offline johnlobo

  • CPC464
  • **
  • Posts: 16
  • Country: es
  • Liked: 9
  • Likes Given: 10
Re: WinCPCTelera
« Reply #90 on: 14:47, 16 August 19 »
Hi Arnaud,


Yes it works in my code. No errors shown, but it goes extraordinarilly fast, much more than in the emulator... is that normal??




Offline Arnaud

  • Supporter
  • 6128 Plus
  • *
  • Posts: 506
  • Country: fr
  • Liked: 418
  • Likes Given: 796
Re: WinCPCTelera
« Reply #91 on: 15:41, 16 August 19 »
Hi Arnaud,


Yes it works in my code. No errors shown, but it goes extraordinarilly fast, much more than in the emulator... is that normal??

Yes and no  :D

WinCPCtelera uses a Window timer with an accuracy 2-5ms and don't have realistic tempo in the cpctelera functions.
Tempo are added in some functions but i haven't found yet the best solution (it's either too slow or too fast)

But you can try to add some wincpct_wait in WinCPCTelera functions and if timing seems better i'll put in my code.

What generaly do, it's put a cpct_waitVSYNC in my main loop.



« Last Edit: 16:32, 16 August 19 by Arnaud »

Offline johnlobo

  • CPC464
  • **
  • Posts: 16
  • Country: es
  • Liked: 9
  • Likes Given: 10
Re: WinCPCTelera
« Reply #92 on: 16:54, 16 August 19 »

Ok.

In my project all the events synced with delays (mainly animations) now go really, really fast.
Only to get  a rough idea of how fast they go, I've added a multiplyer to the index in the loop of waitHalts, and the value that more or less gives me a similar feeling to the emaulator is 2750. This means, that if in my code I have to wait for 25 halts to trigger something, in the windows code, that number is converted to 68.750.


But, that's not really a problem for my purposes because all of them go at the same pace, so I will leave it like this, and if something wierd else happens, I will let you know.



Offline Arnaud

  • Supporter
  • 6128 Plus
  • *
  • Posts: 506
  • Country: fr
  • Liked: 418
  • Likes Given: 796
Re: WinCPCTelera
« Reply #93 on: 17:05, 16 August 19 »
@johnlobo can you try to modify in WinGDI.c :

Code: [Select]
static DWORD WINAPI wincpct_interruptFunction(LPVOID lpParam)
{
SAmstrad* amstrad = (SAmstrad*)lpParam;
DWORD time = timeGetTime();

while (_runInterrupt)
{
if (timeGetTime() - time > INTERRUPT_MS)
{
time = timeGetTime();

if (amstrad->_internalTimer == INTERRUPT_PER_VBL)
{
amstrad->_internalTimer = 0;
SetEvent(_vsyncEvent);
wincpct_redraw();

wincpct_getAsyncJoystickState();
}

if (amstrad->_interruptFunction != NULL)
amstrad->_interruptFunction();

wincpct_renderScreen(amstrad->_internalTimer++);

SetEvent(_EndInterruptEvent);
}

wincpct_wait(5);
}

return 0;
}

If think SetEvent was misplaced :

Code: [Select]
SetEvent(_EndInterruptEvent);
« Last Edit: 17:12, 16 August 19 by Arnaud »

Offline johnlobo

  • CPC464
  • **
  • Posts: 16
  • Country: es
  • Liked: 9
  • Likes Given: 10
Re: WinCPCTelera
« Reply #94 on: 17:24, 16 August 19 »
I did it... but same result... :-(  Still too fast.