Build a cab file and restructure the web pages. I think the only feature I haven't implemented is save snapshot... so no save games I guess yet...
Put in the rest of the configuration for quick navigation... I also did a sortof antialiasing thing to make the fonts in the configuration and load screens more readable. The algorithm is that when I'm going to drop a pixel (every 7th pixel) I look at the 6th pixel and if it's a different colour than the 5th pixel I use it and drop the 7th, if the 6th pixel is the same colour as the 5th then I drop the 6th pixel and use the 7th. This has introduced a slight flicker on the vertical drop lines becuase I actually write the 6th pixel and then rewrite the 7th if appropriate... not perfect but it makes the fonts more readable and I can live with the flicker for now.
OK found my crash. I was memcpy ing data to the frame buffer (GXBeginDraw() etc) but it was triggering the event on window create, before the window actually existed... this was giving an exception (funnily enough). Fixed it with a check that the pointer that I'd got (PIXEL *dst = GXBeginDraw()) actually existed (if (dst)).
I need some sort of screen view available when you're flipped "down" to the keyboard... I'm going for a squashed screen... it's really so you can see that your key presses are doing something... Fixed the load screen that I'd broken in my graphics work.
Right, so I'm back where I was a couple of days ago, but with good performance... Left to do is: better navigation of config/tape picker screens, configuration of custom keys, maybe anti-aliasing for more readable fonts. Only the better navigation is a must for a beta release so hopefully release soon :) (I can play wizball on the tube tomorrow to "test" it... YAY)
Jump points for input area (keyboard and joystick) are all running well. Need to add appropriate jump points on configuration screens. I tried playing a few games today and the performance was noticably slower than I had hoped, however, I had made an even more complicated mess of the graphics system... Basically fuse was calling a call that plotted pixels into the easyCE buffer, then when outputing the screen I would dynamically rotate and scale the buffer to the screen. I have changed this so that now fuse draws scaled rotated pixels directly to a seperate buffer than can be blitted straight to the screen. The performance does seem quite a bit nicer. Need some sort of indication that it's all running good when in keyboard mode (maybe a small screen thing)...
It seemed really happy but I must have busted something... got some exceptions making it crash bad to find :(
Ok, first step to stream line pointer movement I'm setting up a system of jump points, so rather than the cursor moving left 3 pixels, it will move left to the next key or whatever.
Easy CE is based around an assumption that the screen is 240x320. The actual spectrum screen is 256 pixels wide and they eliminate pixels in a number of ways to get it down to 240... What I want to do to get everything landscape and as tidy as possible is change easyCE so that it's internal "screen" is 256x320 pixels so I can load the full spectrum screen and key layouts into it, in portrait like the screen shots in 22-may below. Once I get it's internal screen displaying the right stuff then I'll make some routines that display this internal screen to the smartphone in the manner I want.
Working through the easyCE screen setup stuff... found a few quirks, apart from width being hard coded EVERYWHERE, it also in it's TGA load routine assumes that the tga is the full width of the buffer it's loading into... how nuts is that. Because they use it in several different places I've put a nasty little hardcoded if to change 240 to 256 and leave other things alone... (it's bad coding, but it's only a load routine...) OK, I've got the display going how I want it now, but still outputting in portrait. So now I have the screen as before except the buffer is 256 wide even though the contents are only 240 wide so I have a black strip down the side. I need to find the emulator code that write the "spectrum screen" to the "easy CE screen" and remove their old clipping routines so it writes the full 256 pixels.
Right, that's all done then... Adjusted my pointer routine, put everything sideways, made the voice record button flip between the top (spectrum screen) and bottom (keyboard and options). All looking quite good. I need to focus on the controls now, cos using the keyboard is a pain but survivable, but it doesn't seem to be running a joystick or anything properly yet, and I want to set up a quick mappings system so you can set smartphone keys to be keyboard or joystick actions (which is what you really gonna use during a game). Here's the new screens anyway.
Speed wise, I've now switched it to varios modes, Spectrum 48K mode looks nice and smooth, but Spectrum 128K, plus2 and plu3 are not quite so nice seeming, not hugely slower, but a bit (nothing quantified, just my feeling) I'd say they're not really slow, and certainly future smartphones will rock at this. I think the 48K mode will difintely be a goer for SPV.
Not much work today, I was out to dinner... but:
Figured out why I wasn't getting much joy... my pointer thing could click but it couldn't pendown... this meant the emulated keyboard wasn't going... so I fixed that and:
The control mechanism is terrible and the graphics is awful, but at least it's working... The next step is to get rid of the keyboard and buttons and turn it landscape, that way I can get the screen to dropping 1/7 rows and columns of pixels rather than the current 1/3 which should make it look much nicer. I need some sort of simple menu for the config/tape/sound options (not sure if sounds working properly but that can wait) and some other sort of mechanism to cover keyboard input... I'm thinking it needs to be a little T9ish but I'm not sure cos there's also the keywords against each key which will make them behave differently... Anyway I'll look at that tomorrow. The most promising thing is that it seems to run at a good speed, and also, now I can see stuff running my motivation to tidy it up the rest of the way should be good :)
OK, so PocketClive uses a library called EasyCE... not a good library really for smartphone cos it's full of assumptions, but that's not too important... I've been working on the key mechanism from it tho... Looked in files for WM_KEYDOWN which is the message that the OS sends when a key is pressed. What I found is:
case WM_KEYDOWN:
key = (short)wParam;
if (key == scan_A) b1 = 1;
and it had this for a set of keys, 4 buttons and 4 directions... we want something a bit more generic... I'll leave their code in anyway cos the emulator might use their buttons and they'll still map to smartphone direction keys. Added an array int bx[256] which I'll hold all key states in, in the code above I just added bx[key] = 1; So the array will hold a 1 if any given key is down and a 0 if it's not. It had callbacks like:
bool buttonA()
{
  bool retval = (b1 != 0);
  return retval;
}
So I added another 2 of:
bool buttonX(int x)
{
  bool retval = (bx[x] != 0);
  return retval;
}
bool buttonAny()
{
  for (int i=0; i<256; i++) {
    if (bx[i] !=0)
    return true;
  }
  return false;
}
OK, following through this thing further... it's a total nightmare. The PocketClive side is totally built around screen-stylus input, and EasyCE gives it the x,y co-ordinates of any click... the easiest way to get it working in the first instance (although it'll be a b**** to use) will be to patch a pointer into easyce that I can drive around from the SPV keypad.
Right, that seems to work very well indeed... now I'm gonna find some tape files and see what actually runs :). Later if it's any good I'll need to come back and put a better interface on.
Got back to this kindof... (gonna take it to work so I can do some lunchtime work on it, just don't have the hours at the moment)... anyway... breakpointed the steps as it goes through main() to check where I'm at... the point it was hanging is in a function show_copyright()... I looked in there and it's got a bit where it's waiting for a click
while (!clicked())
update( TRUE, 320 );
Well, it's never gonna get a click because we don't have a stylus... changed this so that it accepts any button press instead. New screenshot... gotta go to work now.
Tracked down the graphics code... I had a couple of false starts with functions that probably aren't used, the thing to look for is calls such as GXBegin or alternately looking in the main loop, try and track down the function call that talks about updates or framesteps or something. In this case I found one called updatedisplay, looking through it it checks for a number of different types of devices (different pocketpcs), but after that it was still making assumptions about output resolutions. This was what causes the "static". So found a loop that looks as follows (again, tracking these things down is a as simple as putting breakpoints in likely locations and seeing which ones it hits.
for ( int y = 0; y < ysize; y++ )
{
memcpy( dst, src, 480 );
dst += 256;
src += 240;
}
So what this is doing is copying a line from the src to the destination and then stepping the pointer for source and dest to the next line. Looking at the code it's copying 240 pixels (480 bytes at 2 pixels per byte). Then it steps the dest by 256 pixels (must be a pocketpc with a 256 wide display) and the src 240 (because the emulated machine is 240 pixels wide). So lets change it so it's nicer for smartphone.
for ( int y = 0; y < ysize; y++ )
{
memcpy( dst, src, 352 );
dst += 176;
src += 240;
}
What it should do now is copy the first 176 pixels of each emulated row to the smartphone screen. This means we'll be losing the right side of the screen, we'll worry about that later, first step is get something sensible on screen :)
Looks good, now we'll make the code slower, but hopefully get a nicer picture... lets drop 1/3 of the pixels in each line (and 1/3 of the lines), it'll look a bit nastier but fit the screen better.
Mmmmm looks nasty but not clipped. That'll be good enough to work on everything else. The options for graphics in the long run are a landscape mode with fewer dropped pixels and if it's quick enough then we can maybe to a bicubic resize rather than a nasty pixel dropping one. Code is:
dst += 8; //we only do this cos our result width is 16 pixels narrower than the screen
for ( int y = 0; y < ysize; y+=3 )
{
for (int x = 0; x<240; x+=3)
{
*(dst++) = *(src++); //do 2 pixels and then drop the third
*(dst++) = *(src++);
src++;
}
dst += 16; //pick up the last 16 output pixels... the loop above only does 160
for (x = 0; x<240; x+=3)
{
*(dst++) = *(src++);
*(dst++) = *(src++);
src++;
}
dst += 16; //we've done a real line twice, this drops the third
src += 240;
}
OK, that's happy now, hopefully all output uses the same method so with luck we won't have to touch this again for a while. Now we need to find input... the first thing I want to add is a way to quit without pulling the battery or using remote process viewer. OK, a bit further investigation... there should be a set of buttons you'd press with the stylus that would let you open roms and stuff... that's why it's hanging... So I need to add a menu to access these dialogues (and probably replace the dialogues too) I'll have a look at this tomorrow.
Loaded the latest PocketClive source into eVC... I needed to compile a couple of library's first as per the original authors instructions but that was trivial. Started doing builds. Tracking the errors from the top of the list downards. The majority of errors at this stage were due to include files not being found. Seperately I loaded file search and for each include not found if it came back in search I updated the path to the correct path (most of them were this problem, I presume the original developer had a heap of include paths already set up) and where they weren't found (such as atlxxx.h) I commented the #include line as these are most likely to elements not available under smartphone. After cleaning up all the #include lines there were only 2 errors remaining which related to the GetModuleName method. This method returns the name and path of the executable itself. Looking at the code it was assuming that windows CE devices would use a function GetModuleFileNameW which doesn't exist under SmartPhone so I changed it to GetModuleFileName (the strings output by this may have type problems but I'll worry about that later if it causes problems.
So now I have a fully compiling executable. I plugged in my phone and ran it in debug mode. It ran and exited cleanly. This means there are no exceptions or memory problems immediately needing dealing with, however the program is obviously not actually working right. For a clean exit (exit (0)) it must either be from an exit(0) call or by the winmain function returning 0. I did a find in files for exit and put a breakpoint on these as well as breakpointing the return 0 in winmain. Ran it again in debug and it broke at the return from winmain. In winmain it sets up a number of things and then call main() then follows up with some cleanup and exit functions, I guessed the problem was in main() and found this. Looking through main there is a whole heap of initialisation calls that run and on error would return (giving the behaviour I had seen). I put breakpoints on all of these return calls and ran the program again. This told me the problem was in a function called init_machines, looking inside this function it looked likely the problem was that it was failing to load a number of files with names like 48.ROM etc... I hadn't put these files in the program directory on my phone. I copied the files over and the emulator ran without hitting any of my breakpoints, it then displayed a screen of static and hung.
From here, I need to look at the graphics functions and figure out why it is displaying static, it will probably be using the wrong screen width etc is my expectation. Additionally I need to stop it hanging, it's not clear whether it was hung or whether I just had no way to enter input as it was probably assuming I had a stylus as I would on a pocket PC. This is where I'll start looking tomorrow.