Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

29 Excellent

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Loading to banked RAM definitely works in C using cc65 for local FS. My libX16 library (https://github.com/CJLove/libX16) supports this. I think that there is an issue with the rom or emulator for r38 preventing this with SD card. Saving from banked RAM only "works" for bank 0. There is an open kernel issue for this: https://github.com/commanderx16/x16-rom/issues/136
  2. Great progress by the team! What is the expected timeframe regarding rom/emulator changes to match the changes to managing banked RAM?
  3. In terms of initializing the array of function pointers you can do that at the time you're declaring the array:
  4. It's been a while since I wrote the code, so I'm going back to my (sadly sparse) dev notes and trying to refresh my memory as I go... The chopper was moving multiple pixels per update (looks like I last had the deltaX set to +/- 4 pixels, deltaY set to +/- 2 pixels if explicitly moving up or down, otherwise deltaY set to 1 pixel for falling due to gravity). Given the chopper sprite's x and y pixel position you can convert that to a tile position and "partial" x/y values (0-7): tileX = x/8; partialX = x mod 8; tileY = y/8; partialY = y mod 8; The chopper was a 64x32 sprite, of which the chopper itself was actually 48x24 centered horizontally (hence a grid of 6x3 underlying tiles). I created equivalent 8 56x24 1bpp bitmaps of each of the 5 chopper sprites (far left, left, center, right, far right) at 8 different horizontal offsets (shifting 1 bit right each time) and had those in banked ram with 1bpp bitmaps of the tileset. Using tileX and tileY you can grab the underlying tiles (a 128x64x2 tilemap in VRAM was converted to an equivalent 128x64x1 map in banked RAM). Using partialX and partialY you could then figure out the right set of bytes from the tileset bitmap and sprite bitmap to do the bitwise compares (https://github.com/CJLove/x16-ChopperRaid/blob/master/src/collision.c#L230). I did get it to work, largely because of a large amount of unit test code (https://github.com/CJLove/x16-ChopperRaid/blob/master/test/test_collision.c) which tested each chopper bitmap against various scenarios of underlying tiles. Getting this to work through interactive testing would have been a non-starter. The key to all of this was compiling the sprite bitmap, tileset and tilemap metadata for banked RAM from graphical assets in Piskel files and Tiled. Some of the conversions were doable with Alovera, others were done with python scripts. One hiccup happened when I decided to double the size of the tileset and forgot about the implications for the corresponding tileset bitmap in banked RAM; that resulted in a lot of "phantom" collisions and chopper explosions. I'm hoping to come back to the project at some point as I had a lot of the game elements working separately, but they "day job" has been taking priority lately.
  5. For the chopper game which I started and haven't had time to get back to for 3+ months (https://github.com/CJLove/x16-ChopperRaid) I had 1-bpp bitmaps of the chopper sprite and of the tileset and a copy of the tilemap in a bank of RAM so collision detection didn't involve accessing VRAM. The collision detection started by grabbing the block of tiles (e.g. a 3x6 grid) directly under the chopper sprite. In the best case, "coarse" detection could detect if the chopper were over any "special" or non-blank tiles and act accordingly. Otherwise (e.g. if the chopper were close to tiles for uneven terrain) it would resort to "fine" detection and do bitwise AND operations between bytes from the chopper bitmap and bytes from the appropriate area of the tile bitmap. If any of the ANDs returned non-zero then there was some sort of pixel collision. My thinking at the time was that even though this was computationally expensive I could allocate processing to separate iterations of the main loop. So if I was only updating chopper movement every 3rd frame (https://github.com/CJLove/x16-ChopperRaid/blob/master/test/test_chopper.c#L52) I could eventually do the collision detection in a separate frame. It was a nice theory at least
  6. As one of the folks using C for the X16 I'd say don't discount it. There are a couple of C examples in the x16-demo repo (https://github.com/commanderx16). I've done a Lode Runner port and a utility library in C (https://github.com/CJLove/x16-LodeRunner). The number of available registers on the 6502 don't make it a great cpu for compiled languages like C. But just like the X16's higher clock speed enables a lot more to be done in BASIC that couldn't be done on the C64 it gives a margin for cases of less than stellar code generation by CC65.
  7. Great progress! The following C code example works with cc65 for writing/reading files with an sdcard image attached to the emulator. If the load/vload worked as well I could add a logging capability to libX16 that would let a program do debug logging to a file for debug purposes. I'd love to support something like that for the host filesystem interface as well someday. #include <string.h> #include <stdio.h> #include <cbm.h> #define MAX_BUF_SIZE 80 int cbmwritefile() { char data[80]; int ssRet=0; char ucDev=8; char filename[20]; int len=0; strcpy(data, "this is just an example text."); len=(int)strlen(data); strcpy(filename, "@0:cbmdata,w"); ssRet = cbm_open(2, ucDev, CBM_WRITE, filename); if(! ssRet) { if(data != NULL) { if(len >= MAX_BUF_SIZE) { len=MAX_BUF_SIZE; data[MAX_BUF_SIZE]='\0'; cbm_write(2, &len, 2); cbm_write(2, data, len); } else { cbm_write(2, &len, 2); cbm_write(2, data, len); } printf("writing file '%s'\r\n", filename); } } else { printf("**error - can't write file: '%s'", filename); } cbm_close(2); return ssRet; } int cbmreadfile() { int ssRet=0; char ucDev=8; char buffer[MAX_BUF_SIZE]; char filename[20]; int flen=0; strcpy(filename, "@0:cbmdata,r"); memset(buffer, 0, MAX_BUF_SIZE); ssRet = cbm_open(2, ucDev, CBM_READ, filename); if(! ssRet) { cbm_read(2, &flen, 2); cbm_read(2, buffer, flen); printf("reading file '%s'\r\nlength: %d [ %d max.]", filename, flen, MAX_BUF_SIZE); printf("\r\ntext : %s\r\n", buffer); } else { printf("**error - can't read file '%s' ", filename); } cbm_close(2); return ssRet; } int main() { int ssRet=0; printf("** filetest 0.2 stdio.h / cbm.h **\n"); printf("calling cbmwritefile()\r\n"); ssRet = cbmwritefile(); printf("err: %d\r\n", ssRet); printf("calling cbmreadfile()\r\n"); ssRet = cbmreadfile(); printf("err: %d\r\n", ssRet); return 0; }
  8. In my code (also C) I've used lower case in source code (string literals, not composed with sprintf()), upper case on disk. This has worked for me on Linux and (briefly) in setting up a new laptop w/Windows 10 to support X16 development.
  9. I'm using C and the cc65 toolchain. For grins I'm a little curious about using Rust for the X16 at some point. There is an alternate Rust compiler (https://github.com/thepowersgang/mrustc) which compiles Rust code into C which could then be compiled with cc65. There was a proof of concept demonstrating this for the C64 (with patches against mrustc and cc65).
  10. While the library and the X16 rom/emulator have been under development and changing it's been nice for the library to be decoupled from cc65. That certainly could be considered once things stabilize.
  11. ChrisL


    Version 0.1.0


    libX16 is a utility library for those using C with the CC65 toolchain for the Commander X16. Library documentation is available from the github page: https://github.com/CJLove/libX16 This is a beta v0.1.0 release of libX16 for the Commander X16 rom version r37 and CC65. The attached artifact includes the library header files and library file for linking. Alternatively the library can be referenced as a git submodule in the .gitmodules file: [submodule "libX16"] path = libX16 url = https://github.com/CJLove/libX16
  12. libX16 View File libX16 is a utility library for those using C with the CC65 toolchain for the Commander X16. Library documentation is available from the github page: https://github.com/CJLove/libX16. Currently it supports loading/saving files to banked RAM and VRAM, playing sound data for the YM2151, and providing a VERA header file with additional constant definitions beyond those provided by CC65. This is a beta v0.1.0 release of libX16 for the Commander X16 rom version r37 and CC65. The attached artifact includes the library header files and library file for linking. Alternatively the library can be referenced as a git submodule in a github repo via the .gitmodules file: [submodule "libX16"] path = libX16 url = https://github.com/CJLove/libX16 Submitter ChrisL Submitted 07/11/20 Category Dev Tools
  13. It is possible with the emulator '-log V' command-line flag to log reads/writes to VRAM addresses, so it might be useful to support some add-on filtering of that emulator output so you could narrow things down to specific VRAM addresses (maybe even specific to the layout of what you're putting where in VRAM). A first cut at this might be to pipe emulator output to a separate script (python?) that could do this filtering; ultimately it would be faster for this to be done in the emulator itself.
  14. Seeing your post now. Welcome!
  15. I tend to agree, as I have my own test code (similar, but using 128x64 map dimensions) which works for layer 0 if it uses the map base that layer 1 would otherwise use (0x00000) but fails for other map base addresses (0x04000, 0x08000, 0x0c000). After modifying my code to test layer 0 and layer 1 separately I think I've found that layer 1 can handle map bases 0x0000, 0x4000, 0x8000, 0xc000 while layer 0 can only handle map base 0x0000. If I switch to have layer 0 use map base 0x0000 and layer 1 use map base 0x4000 then both layers work together (block of tiles on the left is written to layer 1, block of tiles on the right is written to layer 0). Wish we had hardware to try this on ; I guess I'd suspect an emulator bug?
  • Create New...

Important Information

Please review our Terms of Use