Comments (15)
Snapshots in VirtualC64web π.
But I can't image at the moment how this would like from a XP point of view. Using a carousel of some sort is a great idea, I think. But how would the carousel be integrated in the UI. I think it would annoy the user if was displayed all the time, so it needs to pop up in some way π€.
Because there are so many unknowns regarding XP, I recommend to start with a visual prototype or a functional prototype with some pre-saved snapshots in the Rom folder the user can select from.
from virtualc64web.
I think it would annoy the user if was displayed all the time, so it needs to pop up in some way π€.
you are right we need to use popups. fortunately bootstrap gives us some nice options here
https://getbootstrap.com/docs/4.0/components/modal/
I am not so sure with the carousel anymore ... maybe a scrollable modal is much better suited ... from the user expierience aspect ... Scrollable modals are maybe like the netflix selection UI ... oh yes we can implement infinite scrolling and bla bla bla ... π€ I have the strange feeling that I already said this somewhere ? Must be a dejavu ....
from virtualc64web.
bootstrap modal in action π
the next idea is to place a lots of bootstrap card components into it ...
https://getbootstrap.com/docs/4.0/components/card/
from virtualc64web.
cards installed ... π
x-scrolling for one-row-only installed ... π
y-scrolling installed π
Works on touchscreens too.
Here on an iPhone in landscape
Now I need lots of snapshots from the core ...
from virtualc64web.
I can now generate this "netflix like scrollable grid" in javascript right when the snapshots button is clicked π. The rows and cols of the scrollable grid are generated then in javascript which produces the bootstrap html code ...
now I want to feed the new baby πΆπΎ ... I need some snapshots and the pictures for it
the next logical step would be ... on clicking the snapshots button the javascript code connects to the core and pulls the auto and user snapshots out of the core and generates the grid with the pulled information ...
I peeked into the cores API and spotted already some useful bits... π€
userSnapshots
autoSnapshots
and the API methods for them
size_t numSnapshots(vector<Snapshot *> &storage);
size_t numAutoSnapshots() { return numSnapshots(autoSnapshots); }
size_t numUserSnapshots() { return numSnapshots(userSnapshots); }
//! @brief Returns an snapshot from the snapshot storage
Snapshot *getSnapshot(vector<Snapshot *> &storage, unsigned nr);
Snapshot *autoSnapshot(unsigned nr) { return getSnapshot(autoSnapshots, nr); }
Snapshot *userSnapshot(unsigned nr) { return getSnapshot(userSnapshots, nr); }
What I now need is a method which extracts the embedded screenshot of a snapshot as a PNG ... it would be a dream if the data is then already in base64 encoded ... π but UINT8 Array with the PNG would be okay too ...
because I could put this directly into the image element of the grid via its data-URI (https://en.wikipedia.org/wiki/Data_URI_scheme) .. is there maybe some code in the core which can help us to extract the image data ?
When there is no PNG data then we could also use canvas instead of images in the grid and draw the raw data in ABGR8888 format directly into to the canvas elements... but maybe slower ?
from virtualc64web.
Once you have a snapshot object, the image is contained in the snapshot header:
// Snapshot header
typedef struct {
//! @brief Magic bytes ('V','C','6','4')
char magic[4];
//! @brief Version number (V major.minor.subminor)
uint8_t major;
uint8_t minor;
uint8_t subminor;
//! @brief Screenshot
struct {
//! @brief Image width and height
uint16_t width, height;
//! @brief Screen buffer data
uint32_t screen[PAL_RASTERLINES * NTSC_PIXELS];
} screenshot;
//! @brief Date and time of snapshot creation
time_t timestamp;
} SnapshotHeader;
There is a simple API for accessing the snapshot elements:
//! @brief Returns pointer to header data
SnapshotHeader *getHeader() { return (SnapshotHeader *)data; }
//! @brief Returns pointer to core data
uint8_t *getData() { return data + sizeof(SnapshotHeader); }
//! @brief Returns the timestamp
time_t getTimestamp() { return getHeader()->timestamp; }
//! @brief Returns a pointer to the screenshot data.
unsigned char *getImageData() { return (unsigned char *)(getHeader()->screenshot.screen); }
//! @brief Returns the screenshot image width
unsigned getImageWidth() { return getHeader()->screenshot.width; }
//! @brief Returns the screenshot image height
unsigned getImageHeight() { return getHeader()->screenshot.height; }
The image data is a copy of the internal emulator screen buffer. This means all pixels are stores in ABGR or RGBA format (it's the one that is needed by the GPU code, I always get confused which one it is). Donβt get confused by the PAL_RASTERLINES * NTSC_PIXELS
capacity of the image buffer. Because it needs to hold both PAL images and NTSC images, Iβve chosen the larger vertical constant (which is PAL_RASTERLINES) and multiplied it by the larger horizontal constant (which is NTSC_PIXELS).
The VirtualC64 Swift GUI calls some (very ugly) macOS APIs to convert the raw data into an NSImage that can then be displayed inside a GUI element. Maybe the browser has similar capabilities for converting raw pixel formats? π€
from virtualc64web.
Maybe the browser has similar capabilities for converting raw pixel formats?
I fear there is no straight way for this. And I don't like to add another library for this. I am in favour of your approach of keeping code free from bloated dependencies...π I think for the same reason you donβt like those films with tons of characters (like game of Thrones). Or my first superbloated π now retired approach of the supercomplex fps controller π
ππ½There are ways though ...
My favourite is now to use canvas instead of img elements in the cards component ... I tested this and it seems to work very well. Then we can get the 2d context from the canvas and directly draw the saved ABGR screenbuffer from the snapshot.
with the browsers built in canvas API
The createImageData() method creates a new, blank ImageData object. The new object's pixel values are transparent black by default.
For every pixel in an ImageData object there are four pieces of information, the RGBA values:
R - The color red (from 0-255)
G - The color green (from 0-255)
B - The color blue (from 0-255)
A - The alpha channel (from 0-255; 0 is transparent and 255 is fully visible)
So, transparent black indicates: (0,0,0,0).
The color/alpha information is held in an array, and since the array contains 4 pieces of information for every pixel, the array's size is 4 times the size of the ImageData object: width*height*4. (An easier way to find the size of the array, is to use ImageDataObject.data.length)
The array containing the color/alpha information is stored in the data property of the ImageData object.
Tip: After you have manipulated the color/alpha information in the array, you can copy the image data back onto the canvas with the putImageData() method.
The syntax for making the first pixel in the ImageData object red:
imgData=ctx.createImageData(100,100);
imgData.data[0]=255;
imgData.data[1]=0;
imgData.data[2]=0;
imgData.data[3]=255;
Ironical after the job is done ... ππ... we can get a PNG easily from the canvas by calling ...
var canvas = document.getElementById('canvas');
var dataURL = canvas.toDataURL();
console.log(dataURL);
// "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNby
// blAAAADElEQVQImWNgoBMAAABpAAFEI8ARAAAAAElFTkSuQmCC"
.. but then well the snapshots pictures will be already drawn to screen onto the canvas elements ... no need for the PNGs anymore which we needed so badly before for the image elements ...
from virtualc64web.
π€€
We got it ... still needs refinement but the pieces already all working together...
don't ask rambo what happened seconds after snapshot nr0 π¬
from virtualc64web.
don't ask rambo what happened seconds after snapshot nr0
Oh, I see, the blue chopper π¬. I'm sure he made it π. No? π©
It really looks cool. All those nice screenshots side by side in a single browser window.
Once this is done, we need to be capable of loading Roms the same way SAE is. With this capability, VC64web could be deployed directly from the Github repo and tested with a single click π€€.
from virtualc64web.
Once this is done ...
I see that the cores snapshots have no game or source information ... only a number and a timestamp ... initially I wanted to have rows are different games and columns are the different snaphots of a game row... but maybe we would like to postpone that to a future version ... and go for now with a two rows snaphot browers ... the first row auto snapshots and a second row for user taken snapshots. What do you think ?
The colors are not consistent yet ... e.g. background is dark and dialog background is white ... ugly ... have to do some design stuff to make it look nicer... Also it could choose dark/light mode automatically from the OS setting ....
we need to be capable of loading Roms the same way SAE is. With this capability, VC64web could be deployed directly from the Github repo and tested with a single click π€€.
with a single click would be cool ... but there are 5 different .bin files ... are they all copy protected ? Or could we embed at least the chars or the basic bin file ? Or we put these files into the browsers local storage so this has only to be done once ... and on repeated starts of the emulator we check if the roms are still in the local storage and read it from there ... this loading method would be even more convenient as the SAE way where you have to set the roms each time you visit the web site I think...
see here https://www.sitepoint.com/html5-local-storage-revisited/
from virtualc64web.
only a number and a timestamp
Yes, there's just a time stamp. The emulator doesn't know anything about the file where the disk came from.
and go for now with a two rows snaphot browers ... the first row auto snapshots and a second row for user taken snapshots. What do you think ?
Sounds good to me. It pretty much reflects what the Snapshot browser in VC64mac does.
The colors are not consistent yet ...
I love colors π
are they all copy protected ?
Yes π’
Or could we embed at least the chars
No π’
or the basic bin file ?
No π’
Or we put these files into the browsers local storage
Yes π
Great idea. I didn't know it's possible.
from virtualc64web.
you see ... auto snapshots on the top row and user snapshots in the bottom row ... there is a tooltip to the left of each row when your mouse hovers over it... by clicking on one picture it immediatly restores the core in the background π
there is a problem with auto snapshots though ... when I open up the snapshot browser it still takes auto snapshots in the background ... and unfortunately it numbers the snapshots starting from the newest to th oldest, that means the newest snapshot will always be number 0 ... that brings up the problem that when I click on a auto snapshot to restore it .. the number is already outdated and it restores a snapshot which was taken later in time ...
How to solve ? I could stop it taking auto snapshots when opening up the browser by setting
c64->setTakeAutoSnapshots(false);
and enable it again when closing the snapshot browser ..
or can I somehow tell the core to number the snapshots starting from the other end ... that is ... 1 for the oldest and higher numbers for the newer ones ? ...
or should we pause the emulation ?
from virtualc64web.
there is a problem with auto snapshots though ... when I open up the snapshot browser it still takes auto snapshots in the background ..
When I developed the auto-snapshot feature, I stumbled about the exact same issue, too. Bottom line is: Even if you get the numbering right, the user gets confused when the snapshot storage keeps changing. The solution is simple: Disable auto-snapshots temporarily. This is what VC64mac does and there is a special API for that π:
/*! @brief Disables the auto-snapshot feature temporarily.
* @details This method is called when the snaphshot browser opens.
*/
void suspendAutoSnapshots();
/*! @brief Heals a call to suspendAutoSnapshots()
* @details This method is called when the snaphshot browser closes.
*/
void resumeAutoSnapshots();
You could also call c64->setTakeAutoSnapshots(false);
. In this case, you would have to remember yourself if auto-snapshots were switched on or off before disabling them. Otherwise, you would not be able to restore the previous state.
from virtualc64web.
Heals a call to suspendAutoSnapshots()
βHealsβ π€€ππ
from virtualc64web.
with the cores suspend and resume API methods it works now like a charm ...π
I guess I will close the feature-issue, as it is interconnected now... I will follow the idea of saving selected snapshots to the browsers local storage later ...
Once this is done, we need to be capable of loading Roms the same way SAE is. With this capability, VC64web could be deployed directly from the Github repo and tested with a single click π€€.
first I will do do your request π€ with the outsourcing of the roms ... and letting the user put them into its browsers local storage π...
from virtualc64web.
Related Issues (20)
- Running C64-Cursor on iPad/Safari HOT 5
- compiling errors HOT 3
- cannot start D64 when building with latest emsdk HOT 5
- stuck physical keyboard on certain key combinations HOT 2
- Set other ROMs as default? HOT 5
- Does not load basic programs properly HOT 13
- margin-bottom on virtual keyboard for modern iOS devices HOT 1
- Bruce Lee crashes (any version) after several levels HOT 27
- setting action buttons on top of nav bar HOT 1
- improve mapping of (short cut) keys HOT 2
- work on defining actions and keyboard mappings
- Touch controls in iPhone HOT 41
- How does one drag a link from csdb.dk into the drop zone? HOT 4
- Touch controls in iPhone Part2 HOT 12
- use HOT 1
- xbox wireless controllers axis sticks HOT 1
- Touch example crashes on touch devices HOT 3
- Unable to select c64 roms on iOS HOT 2
- reworked css based virtual keyboard HOT 3
- Datasette STOP and PLAY HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from virtualc64web.