I thought I would try using UltraEdit search and replace to see how far I could get with my C to C BASIC symbol translation. I think this method is going to work fine. The following list was used in a REPLACE ALL mode. My final step would be to do interactive search and replaces to get the symbols that may have dual meaning. (like * for math and as a PTR)
{ = BEGIN
} = END
return = RETURN
if = IF
for = FOR
while = WHILE
switch = SELECT_CASE
case = CASE
break; = END_CASE
default: = CASE_ELSE
END else BEGIN = ELSE
END else = ELSE_IF
IF
&& = AND
|| = OR
== = EQ
fprintf = PRINT_FILE
printf = PRINT
Here is the results of the above search and replaces.
/* Simple program: Move N sprites around on the screen as fast as possible */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <time.h>
#include <SDL/SDL.h>
#include "cbasic.h"
#define NUM_SPRITES 100
#define MAX_SPEED 1
SDL_Surface *sprite;
int numsprites;
SDL_Rect *sprite_rects;
SDL_Rect *positions;
SDL_Rect *velocities;
int sprites_visible;
int debug_flip;
Uint16 sprite_w, sprite_h;
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void quit(int rc)
BEGIN
SDL_Quit();
exit(rc);
END
int LoadSprite(char *file)
BEGIN
SDL_Surface *temp;
/* Load the sprite image */
sprite = SDL_LoadBMP(file);
IF ( sprite EQ NULL ) BEGIN
PRINT_FILE(stderr, "Couldn't load %s: %s", file, SDL_GetError());
RETURN(-1);
END
/* Set transparent pixel as the pixel at (0,0) */
IF ( sprite->format->palette ) BEGIN
SDL_SetColorKey(sprite, (SDL_SRCCOLORKEY|SDL_RLEACCEL),
*(Uint8 *)sprite->pixels);
END
/* Convert sprite to video FORmat */
temp = SDL_DisplayFormat(sprite);
SDL_FreeSurface(sprite);
IF ( temp EQ NULL ) BEGIN
PRINT_FILE(stderr, "Couldn't convert background: %s\n",
SDL_GetError());
RETURN(-1);
END
sprite = temp;
/* We're ready to roll. :) */
RETURN(0);
END
void MoveSprites(SDL_Surface *screen, Uint32 background)
BEGIN
int i, nupdates;
SDL_Rect area, *position, *velocity;
nupdates = 0;
/* Erase all the sprites IF necessary */
IF ( sprites_visible ) BEGIN
SDL_FillRect(screen, NULL, background);
END
/* Move the sprite, bounce at the wall, and draw */
FOR ( i=0; i<numsprites; ++i ) BEGIN
position = &positions[i];
velocity = &velocities[i];
position->x += velocity->x;
IF ( (position->x < 0) OR (position->x >= (screen->w - sprite_w)) ) BEGIN
velocity->x = -velocity->x;
position->x += velocity->x;
END
position->y += velocity->y;
IF ( (position->y < 0) OR (position->y >= (screen->h - sprite_w)) ) BEGIN
velocity->y = -velocity->y;
position->y += velocity->y;
END
/* Blit the sprite onto the screen */
area = *position;
SDL_BlitSurface(sprite, NULL, screen, &area);
sprite_rects[nupdates++] = area;
END
IF (debug_flip) BEGIN
IF ( (screen->flags & SDL_DOUBLEBUF) EQ SDL_DOUBLEBUF ) BEGIN
static int t = 0;
Uint32 color = SDL_MapRGB (screen->format, 255, 0, 0);
SDL_Rect r;
r.x = (sin((float)t * 2 * 3.1459) + 1.0) / 2.0 * (screen->w-20);
r.y = 0;
r.w = 20;
r.h = screen->h;
SDL_FillRect (screen, &r, color);
t+=2;
END
END
/* Update the screen! */
IF ( (screen->flags & SDL_DOUBLEBUF) EQ SDL_DOUBLEBUF ) BEGIN
SDL_Flip(screen);
ELSE
SDL_UpdateRects(screen, nupdates, sprite_rects);
END
sprites_visible = 1;
END
/* This is a way of telling whether or not to use hardware surfaces */
Uint32 FastestFlags(Uint32 flags, int width, int height, int bpp)
BEGIN
const SDL_VideoInfo *info;
/* Hardware acceleration is only used in fullscreen mode */
flags |= SDL_FULLSCREEN;
/* Check FOR various video capabilities */
info = SDL_GetVideoInfo();
IF ( info->blit_hw_CC AND info->blit_fill ) BEGIN
/* We use accelerated colorkeying and color filling */
flags |= SDL_HWSURFACE;
END
/* If we have enough video memory, and will use accelerated
blits directly to it, then use page flipping.
*/
IF ( (flags & SDL_HWSURFACE) EQ SDL_HWSURFACE ) BEGIN
/* Direct hardware blitting without double-buffering
causes really bad flickering.
*/
IF ( info->video_mem*1024 > (height*width*bpp/8) ) BEGIN
flags |= SDL_DOUBLEBUF;
ELSE
flags &= ~SDL_HWSURFACE;
END
END
/* Return the flags */
RETURN(flags);
END
int main(int argc, char *argv[])
BEGIN
SDL_Surface *screen;
Uint8 *mem;
int width, height;
Uint8 video_bpp;
Uint32 videoflags;
Uint32 background;
int i, done;
SDL_Event event;
Uint32 then, now, frames;
/* Initialize SDL */
IF ( SDL_Init(SDL_INIT_VIDEO) < 0 ) BEGIN
PRINT_FILE(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
RETURN(1);
END
numsprites = NUM_SPRITES;
videoflags = SDL_SWSURFACE|SDL_ANYFORMAT;
width = 640;
height = 480;
video_bpp = 8;
debug_flip = 0;
WHILE ( argc > 1 ) BEGIN
--argc;
IF ( strcmp(argv[argc-1], "-width") EQ 0 ) BEGIN
width = atoi(argv[argc]);
--argc;
ELSE_IF ( strcmp(argv[argc-1], "-height") EQ 0 ) BEGIN
height = atoi(argv[argc]);
--argc;
ELSE_IF ( strcmp(argv[argc-1], "-bpp") EQ 0 ) BEGIN
video_bpp = atoi(argv[argc]);
videoflags &= ~SDL_ANYFORMAT;
--argc;
ELSE_IF ( strcmp(argv[argc], "-fast") EQ 0 ) BEGIN
videoflags = FastestFlags(videoflags, width, height, video_bpp);
ELSE_IF ( strcmp(argv[argc], "-hw") EQ 0 ) BEGIN
videoflags ^= SDL_HWSURFACE;
ELSE_IF ( strcmp(argv[argc], "-flip") EQ 0 ) BEGIN
videoflags ^= SDL_DOUBLEBUF;
ELSE_IF ( strcmp(argv[argc], "-debugflip") EQ 0 ) BEGIN
debug_flip ^= 1;
ELSE_IF ( strcmp(argv[argc], "-fullscreen") EQ 0 ) BEGIN
videoflags ^= SDL_FULLSCREEN;
ELSE_IF ( isdigit(argv[argc][0]) ) BEGIN
numsprites = atoi(argv[argc]);
ELSE
PRINT_FILE(stderr,
"Usage: %s [-bpp N] [-hw] [-flip] [-fast] [-fullscreen] [numsprites]\n",
argv[0]);
quit(1);
END
END
/* Set video mode */
screen = SDL_SetVideoMode(width, height, video_bpp, videoflags);
IF ( ! screen ) BEGIN
PRINT_FILE(stderr, "Couldn't set %dx%d video mode: %s\n",
width, height, SDL_GetError());
quit(2);
END
SDL_WM_SetCaption("C BASIC SDL 1.2 Sprites",0);
/* Load the sprite */
IF ( LoadSprite("icon.bmp") < 0 ) BEGIN
quit(1);
END
/* Allocate memory FOR the sprite info */
mem = (Uint8 *)malloc(4*sizeof(SDL_Rect)*numsprites);
IF ( mem EQ NULL ) BEGIN
SDL_FreeSurface(sprite);
PRINT_FILE(stderr, "Out of memory!\n");
quit(2);
END
sprite_rects = (SDL_Rect *)mem;
positions = sprite_rects;
sprite_rects += numsprites;
velocities = sprite_rects;
sprite_rects += numsprites;
sprite_w = sprite->w;
sprite_h = sprite->h;
srand(time(NULL));
FOR ( i=0; i<numsprites; ++i ) BEGIN
positions[i].x = rand()%(screen->w - sprite_w);
positions[i].y = rand()%(screen->h - sprite_h);
positions[i].w = sprite->w;
positions[i].h = sprite->h;
velocities[i].x = 0;
velocities[i].y = 0;
WHILE ( ! velocities[i].x AND ! velocities[i].y ) BEGIN
velocities[i].x = (rand()%(MAX_SPEED*2+1))-MAX_SPEED;
velocities[i].y = (rand()%(MAX_SPEED*2+1))-MAX_SPEED;
END
END
background = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
/* Print out inFORmation about our surfaces */
PRINT("Screen is at %d bits per pixel\n",screen->format->BitsPerPixel);
IF ( (screen->flags & SDL_HWSURFACE) EQ SDL_HWSURFACE ) BEGIN
PRINT("Screen is in video memory\n");
ELSE
PRINT("Screen is in system memory\n");
END
IF ( (screen->flags & SDL_DOUBLEBUF) EQ SDL_DOUBLEBUF ) BEGIN
PRINT("Screen has double-buffering enabled\n");
END
IF ( (sprite->flags & SDL_HWSURFACE) EQ SDL_HWSURFACE ) BEGIN
PRINT("Sprite is in video memory\n");
ELSE
PRINT("Sprite is in system memory\n");
END
/* Run a sample blit to trigger blit acceleration */
BEGIN SDL_Rect dst;
dst.x = 0;
dst.y = 0;
dst.w = sprite->w;
dst.h = sprite->h;
SDL_BlitSurface(sprite, NULL, screen, &dst);
SDL_FillRect(screen, &dst, background);
END
IF ( (sprite->flags & SDL_HWACCEL) EQ SDL_HWACCEL ) BEGIN
PRINT("Sprite blit uses hardware acceleration\n");
END
IF ( (sprite->flags & SDL_RLEACCEL) EQ SDL_RLEACCEL ) BEGIN
PRINT("Sprite blit uses RLE acceleration\n");
END
/* Loop, blitting sprites and waiting FOR a keystroke */
frames = 0;
then = SDL_GetTicks();
done = 0;
sprites_visible = 0;
WHILE ( !done ) BEGIN
/* Check FOR events */
++frames;
WHILE ( SDL_PollEvent(&event) ) BEGIN
SELECT_CASE (event.type) BEGIN
CASE SDL_MOUSEBUTTONDOWN:
SDL_WarpMouse(screen->w/2, screen->h/2);
END_CASE
CASE SDL_KEYDOWN:
/* Any keypress quits the app... */
CASE SDL_QUIT:
done = 1;
END_CASE
CASE_ELSE
END_CASE
END
END
MoveSprites(screen, background);
END
SDL_FreeSurface(sprite);
free(mem);
/* Print out some timing inFORmation */
now = SDL_GetTicks();
IF ( now > then ) BEGIN
PRINT("%2.2f frames per second\n",
((double)frames*1000)/(now-then));
END
SDL_Quit();
RETURN(0);
END
I had to add a BEGIN and END #define as I'm a little more verbose with the traditional version of C BASIC. I'm happy to say that the REPLACE ALL work great except for the FOR as it picked up the SDL format and change it to upper case. (not allowing the program to compile in that state) After repairing the format case changes it compiled fine. For now this method will save me a lot of time as I continue to refine my C BASIC keyword list. The fully converted testsprite.c example can be found in the C BASIC GUI thread.
FOR replace missteps
jrs@laptop:~/C_BASIC/xlate$ make -B -f Makefile.cbsr
gcc -g -O2 -D_GNU_SOURCE=1 -D_REENTRANT -DHAVE_OPENGL xsprite.c -o xsprite
xsprite.c: In function ‘LoadSprite’:
xsprite.c:43:13: error: ‘SDL_Surface’ has no member named ‘FORmat’
IF ( sprite->FORmat->palette ) BEGIN
^
xsprite.c: In function ‘MoveSprites’:
xsprite.c:98:37: error: ‘SDL_Surface’ has no member named ‘FORmat’
Uint32 color = SDL_MapRGB (screen->FORmat, 255, 0, 0);
^
xsprite.c: In function ‘main’:
xsprite.c:248:32: error: ‘SDL_Surface’ has no member named ‘FORmat’
background = SDL_MapRGB(screen->FORmat, 0x00, 0x00, 0x00);
^
xsprite.c:251:49: error: ‘SDL_Surface’ has no member named ‘FORmat’
PRINT("Screen is at %d bits per pixel\n",screen->FORmat->BitsPerPixel);
^
make: *** [xsprite] Error 1
jrs@laptop:~/C_BASIC/xlate$
jrs@laptop:~/C_BASIC/xlate$ make -B -f Makefile.cbsr
gcc -o xsprite xsprite.c -g -O2 -D_GNU_SOURCE=1 -D_REENTRANT -DHAVE_OPENGL -lSDL -lm
jrs@laptop:~/C_BASIC/xlate$
UltraEdit has a nice feature that allows for multiple copy buffers. This will help with the BEGIN/END second round make-over to give it the more traditional BASIC look. I'm pretty sure I can automate at least the REPLACE ALL steps with a SB script and do the FOR/TO/STEP changes. In all I would say this is a 10X improvement over how I was doing it before. (keyword by keyword) As it turned out, using Daniel's uCalc Transform tool for this would probably have been overkill.