I thought I would start the C BASIC conversion of the Wetspot II game. So far these changes compile and the game runs. The goal is to make this game's C code look as close to BASIC as we can. A syntax colored version of the original wetspot2.c program is attached as a PDF.
FYI - C BASIC syntax notes.
* I'm using the _ with THEN and ELSE for single IFs and simple IF/THEN/ELSE statements. I will try to keep this concept going forward with other dual purpose keywords.
then used with multi-line IF
then_ used with single line IF
else_ is the else replacement and else_if will replace the C else if.
call optional but I think it helps distinguished between a function/sub call and a C variable declaration. It's your call to use it or not.
let on-the-fly C variable assignments
incr incrementing variable
mod_ replaces the C % modulus operator
and_ replaces the C && AND operator
or_ replaces the C || OR operator
begin_for starts a FOR/NEXT loop
to_ used in FOR/NEXT
step used in FOR/NEXT
begin_for starts the FOR/NEXT loop
next ends/iterates the FOR/NEXT loop
select_case a more BASIC like substitute for the C SWITCH statement
begin_select starts a SELECT/CASE block
_to_ used in the CASE statement to indicate a range
case_else replaces the C Default: SWITCH keyword
end_case ends a CASE block
end_select ends the SELECT block
// C BASIC
#define function
#define method
#define gosub
#define call
#define let
#define incr
#define dim
#define as
#define then_
#define then {
#define else_ } else {
#define sub void
#define begin {
#define begin_if {
#define begin_function {
#define begin_sub {
#define end }
#define end_if }
#define end_function }
#define end_sub }
#define and_ &&
#define or_ ||
#define mod_ %
#define class typedef struct
#define types typedef struct
#define methods
#define member ->
#define addressof &
#define has =
#define NewSpace malloc
#define FreeSpace free
#define select_case switch
#define begin_select {
#define end_case break;
#define case_else default:
#define end_select }
#define to_ ;
#define _to_ ...
#define begin_for {
#define step ;
#define next }
#define create(A,B,C) A B=malloc((C)*sizeof(*B))
#define copy(A,B,C) CopyInts((int*)A,(int*)B,C);
// Wetspot II
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <SDL/SDL.h>
#include <SDL/SDL_mixer.h>
#include "wetspot2.h"
#include "font.h"
#include "palette.h"
#include "timer.h"
#include "logo.h"
#include "sprites.h"
#include "menu.h"
#include "world.h"
#include "input.h"
#include "sound.h"
/*
COMMON SHARED Game AS GameType
COMMON SHARED Player() AS PlayerType
COMMON SHARED Enemy() AS EnemyType
COMMON SHARED Object() AS ObjectType
COMMON SHARED Block() AS BlockType
COMMON SHARED Shot() AS ShotType
COMMON SHARED Death() AS DeathType
COMMON SHARED Cel() AS INTEGER
COMMON SHARED Blocked AS INTEGER
*/
dim as SDL_Surface *screen;
dim as SDL_Surface *gamescreen;
dim as SDL_Surface *theend;
dim as Uint8 *keys;
dim as GAMETYPE Game;
dim as PLAYERTYPE Player[2];
dim as ENEMYTYPE Enemy[MAXENEMIES];
dim as OBJECTTYPE Object[MAXOBJS];
dim as BLOCKTYPE Block[MAXBLOCKS];
dim as SHOTTYPE Shot[MAXSHOTS];
dim as DEATHTYPE Death[2];
dim as CELL cell[12][20];
dim as int Blocked;
/*
SUB CheckScore (PlayerNum)
' Checks if the player has gained enough points for an extra life
IF Player(PlayerNum).score >= Player(PlayerNum).nextextra THEN
IF Player(PlayerNum).nextextra = 30000 THEN Player(PlayerNum).nextextra = 0
Player(PlayerNum).nextextra = Player(PlayerNum).nextextra + 100000
Player(PlayerNum).lives = Player(PlayerNum).lives + 1
PlaySound 7
END IF
*/
sub CheckScore(int PlayerNum)
begin_sub
if(Player[PlayerNum].score >= Player[PlayerNum].nextextra) then
if(Player[PlayerNum].nextextra == 30000) then_ Player[PlayerNum].nextextra = 0;
Player[PlayerNum].nextextra += 100000;
incr Player[PlayerNum].lives++;
call PlaySound(7);
end_if
end_sub
/*
DIM SHARED dx(4) AS INTEGER, dy(4) AS INTEGER
' direction can be: 0 = right, 1 = up, 2 = left, 3 = down, 4 = nowhere
DATA 0,1,-1,0,0,-1,1,0,0,0
' Gets axis dx/dy increase/decrease in each direction
FOR i = 0 TO 4
READ dx(i), dy(i)
NEXT i
*/
dim as int dx[5] = {0, -1, 0, 1, 0};
dim as int dy[5] = {1, 0, -1, 0, 0};
call int GetFreeObject();
call void KillEnemy(int);
/*
SUB CheckStatus
' Checks game status and other minor game features
' Finds if all the players are dead; in that case, ends the game loop
IF Game.players = 0 THEN
IF Player(0).dead = TRUE THEN Game.status = 400: Player(0).dead = 2
ELSE
IF Player(0).dead = TRUE THEN
Player(0).dead = 2
IF Player(0).dead >= 2 AND Player(1).dead >= 2 THEN Game.status = 400
END IF
IF Player(1).dead = TRUE THEN
Player(1).dead = 2
IF Player(0).dead >= 2 AND Player(1).dead >= 2 THEN Game.status = 400
END IF
END IF
' Randomly adds a bonus object on the screen (if possible)
IF Game.objects < 3 AND Game.status <> -501 THEN
IF Game.status < 1 AND Game.time > 15 THEN
IF INT(RND(1) * 100) = 0 THEN
FOR i = 0 TO MAXOBJS
IF Object(i).typ = 0 THEN EXIT FOR
NEXT i
Object(i).x = INT(RND(1) * 20)
Object(i).y = INT(RND(1) * 12)
GetBlockInfo Cel(Object(i).x, Object(i).y)
IF st = 0 THEN
Object(i).typ = 26 + INT(RND(1) * 8)
Object(i).time = 0
IF INT(RND(1) * 3) = 0 THEN
xi = INT(RND(1) * 20): yi = INT(RND(1) * 12)
GetBlockInfo Cel(xi, yi)
IF rd > 0 THEN Object(i).typ = rd
IF Game.mode = DEMO AND Object(i).typ = 14 THEN Object(i).typ = 0
END IF
IF INT(RND(1) * 3) = 0 THEN Object(i).typ = INT(RND(1) * 33) + 1
Game.objects = Game.objects + 1
END IF
END IF
END IF
END IF
SELECT CASE Game.status
CASE -500 TO -3
' The enemies are blocked by the clock
Game.status = Game.status + 1
IF Game.status = -2 THEN
' Resumes the enemies
Game.status = 0
IF Game.time < 16 THEN
ChangePal 0
ELSE
ChangePal -1
END IF
END IF
CASE -2
' Do the lightnings
FOR i = 0 TO 80
DrawScreen
NEXT i
Game.status = 0
FOR i = 0 TO MAXENEMIES
IF Enemy(i).typ > 0 THEN KillEnemy i
NEXT i
ChangePal -1
CASE -1
' Do the earthquake
Game.status = 0
FOR i = 0 TO 100
WAIT &H3DA, 8, 8: WAIT &H3DA, 8
BlastCopy VARSEG(Buffer(0)), VARPTR(Buffer(0)), &HA000, ((i MOD 3) * 320)
NEXT i
FOR i = 0 TO MAXENEMIES
IF Enemy(i).typ > 0 THEN KillEnemy i
NEXT i
CASE IS > 0
Game.status = Game.status + 1
END SELECT
*/
sub CheckStatus()
begin_sub
if(Game.players == 1) then
if(Player[0].dead == TRUE) then
Game.status = 400;
Player[0].dead = 2;
end_if
else_
if(Player[0].dead == TRUE) then
Player[0].dead = 2;
if(Player[0].dead >= 2 and_ Player[1].dead >= 2) then_ Game.status = 400;
end_if
if(Player[1].dead == TRUE) then
Player[1].dead = 2;
if(Player[0].dead >= 2 and_ Player[1].dead >= 2) then_ Game.status = 400;
end_if
end_if
if(Game.objects < 3 and_ Game.status != -501) then
if(Game.status < 1 and_ Game.time > 15) then
if(rand() mod_ 100 == 0) then //INT(RND(1) * 100)
let int i = GetFreeObject();
Object[i].x = rand() mod_ 20; //INT(RND(1) * 20)
Object[i].y = rand() mod_ 12; //INT(RND(1) * 12)
if(cell[Object[i].y][Object[i].x].st == 0) then
Object[i].typ = 26 + rand() mod_ 8; //INT(RND(1) * 8)
Object[i].time = 0;
if(rand() mod_ 2 == 0) then //INT(RND(1) * 3)
let int xi = rand() mod_ 20; //INT(RND(1) * 20):
let int yi = rand() mod_ 12; //INT(RND(1) * 12)
if(cell[yi][xi].rd > 0) then_ Object[i].typ = cell[yi][xi].rd;
if(Game.mode == DEMO and_ Object[i].typ == 14) then_ Object[i].typ = 0;
end_if
if(rand() mod_ 3 == 0) then_ Object[i].typ = rand() mod_ 33 + 1;
incr Game.objects++;
end_if
end_if
end_if
end_if
select_case (Game.status)
begin_select
case -500 _to_ -3:
// The enemies are blocked by the clock
incr Game.status++;
if(Game.status == -2) then
// Resumes the enemies
Game.status = 0;
if(Game.time < 16) then
//ChangePal 0
else_
//ChangePal -1
end_if
end_if
end_case
case -2:
// Do the lightnings
Game.status = 0;
for(int i = 0 to_ i < 80 step i++)
begin_for
call DrawScreen();
next
for(int i = 0 to_ i < MAXENEMIES step i++)
begin_for
if(Enemy[i].typ > 0) then_ call KillEnemy(i);
next
//ChangePal -1
end_case
case -1:
// Do the earthquake
Game.status = 0;
/*for(int i = 0 TO 100
WAIT &H3DA, 8, 8: WAIT &H3DA, 8
BlastCopy VARSEG(Buffer(0)), VARPTR(Buffer(0)), &HA000, ((i MOD 3) * 320)
NEXT i*/
for(int i = 0 to_ i < MAXENEMIES step i++)
begin_for
if(Enemy[i].typ > 0) then_ call KillEnemy(i);
next
end_case
case_else
if(Game.status > 0) then_ incr Game.status++;
end_select
The last functions isn't finished (closed) yet. (working on it)