Hello, all.

Those of you with a good memory might remember me on this forum about a year ago saying something about ASM programming and a game called FlopNinja that I wanted to program as a standalone bootable application.

At any rate I got fed up with trying to figure out how to set up boot code whilst not knowing a single thing about win32 programming (or anything else about programming for that matter).

So finally I broke out of my self-furnished mental straitjacket and decided that I just wanted to program SOMETHING THAT WORKS.

Thus ensued a midnight internet rampage and I managed to find the Test Department tutorials here. I still wanted to use FASM so I wasn't able to do much with it, but then I mysteriously discovered the win32 template that had been in the FASM directory for who knows how long (!). Yay, I'm actually beginning to understand something.

So, I opened up the .asm file for Minipad and decided to try and do the wing-it thing and learn that way. I came up with this. Basically it was copy-and paste, look at the compiler errors and figure out what was wrong, fix it, etc. Now I've found an error that I can't trace.

Code is below, copy and paste into FASM to see what I'm talking about. All dependencies are in the FASM include directory. Error is in the resource section when I start building the menubar for the window.


; Template for program using standard Win32 headers

format PE GUI 4.0
entry start

include 'win32w.inc'

MENU_NEW  = 101
MENU_ABOUT = 102
MENU_HELP  = 103
MENU_EXIT  = 104

section '.data' data readable writeable

  _class TCHAR 'FASMWIN32',0
  _title TCHAR 'Win32 program template',0
  _error TCHAR 'Startup failed.',0

  _about_title TCHAR 'About',0
  _about_text  TCHAR 'This is FirstApp, my First App.',0

  wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class

  msg MSG

section '.code' code readable executable

  start:

        invoke  GetModuleHandle,0            ;Getting window ID (handle)
        mov    ,eax            ;putting ID into variable wc.hInstance
        invoke  LoadIcon,0,IDI_APPLICATION    ;giving our window an icon
        mov    ,eax
        invoke  LoadCursor,0,IDC_ARROW        ;loading a cursor (otherwise the mouse arrow would disappear when it went over our window).
        mov    ,eax
        invoke  RegisterClass,wc              ;Registering all this via RegisterClass, wc=using wc.* variables.
        test    eax,eax
        jz      error

        invoke  LoadMenu,,37
        invoke  CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128,128,480,320,NULL,NULL,,NULL  ;creating window.
        test    eax,eax
        jz      error

  msg_loop:                                  ;Waits for message. If message found, TranslateMessage calls the appropriate code block.
        invoke  GetMessage,msg,NULL,0,0
        cmp    eax,1
        jb      end_loop
        jne    msg_loop
        invoke  TranslateMessage,msg
        invoke  DispatchMessage,msg
        jmp    msg_loop

  error:
        invoke  MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK

  end_loop:
        invoke  ExitProcess,

proc WindowProc hwnd,wmsg,wparam,lparam
        push    ebx esi edi
        cmp    ,WM_DESTROY
        je      .wmdestroy
  .defwndproc:
        invoke  DefWindowProc,,,,
        jmp    .finish
  .wmcommand:                                ;compares message string and calls the appropriate code block.
        mov    eax,
        and    eax,0FFFFh
        cmp    eax,MENU_NEW
        je      .new
        cmp    eax,MENU_ABOUT
        je      .about
        cmp    eax,MENU_HELP
        je      .help
        cmp    eax,MENU_EXIT
        je      .wmdestroy
        jmp    .defwndproc
      .new:
        jmp    .finish
      .about:
        invoke  MessageBox,,_about_text,_about_title,MB_OK
        jmp    .finish
      .help:
        jmp    .finish
  .wmdestroy:                                ;Exit
        invoke  PostQuitMessage,0
        xor    eax,eax
  .finish:                                    ;Return
        pop    edi esi ebx
        ret
endp

section '.idata' import data readable writeable

  library kernel32,'KERNEL32.DLL',\
          user32,'USER32.DLL'

  include 'api\kernel32.inc'
  include 'api\user32.inc'

  import kernel,\
        GetModuleHandle,'GetModuleHandleA',\
        ExitProcess,'ExitProcess'

  import user,\
        RegisterClass,'RegisterClassA',\
        CreateWindowEx,'CreateWindowExA',\
        DefWindowProc,'DefWindowProcA',\
        SetWindowLong,'SetWindowLongA',\
        RedrawWindow,'RedrawWindow',\
        GetMessage,'GetMessageA',\
        TranslateMessage,'TranslateMessage',\
        DispatchMessage,'DispatchMessageA',\
        SendMessage,'SendMessageA',\
        LoadCursor,'LoadCursorA',\
        LoadIcon,'LoadIconA',\
        LoadMenu,'LoadMenuA',\
        GetClientRect,'GetClientRect',\
        MoveWindow,'MoveWindow',\
        SetFocus,'SetFocus',\
        MessageBox,'MessageBoxA',\
        PostQuitMessage,'PostQuitMessage'

section '.rsrc' resource data readable

  ; resource directory

  directory RT_MENU,menus,\
            RT_ICON,icons,\
            RT_GROUP_ICON,group_icons,\
            RT_VERSION,versions

  ; resource subdirectories

  resource menus,\
          37,LANG_ENGLISH+SUBLANG_DEFAULT,menu_bar

  resource icons,\
          1,LANG_NEUTRAL,icon_data

  resource group_icons,\
          17,LANG_NEUTRAL,main_icon

  resource versions,\
          1,LANG_NEUTRAL,version

  menu menu_bar
      menuitem '&File',0
                menuitem '&New',MENU_NEW
                menuseparator
                menuitem 'E&xit',MENU_EXIT
      menuitem '&Help',MENU_HELP
                menuitem '&About...',MENU_ABOUT

  icon main_icon,icon_data,'minipad.ico'

  versioninfo version,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+SUBLANG_DEFAULT,0,\
              'FileDescription','FirstApp - my First App',\
              'LegalCopyright','No rights reserved.',\
              'FileVersion','0.0',\
              'ProductVersion','0.0',\
              'OriginalFilename','FirstApp.exe'


p.s. I still plan on doing FlopNinja once I feel I have a handle on the important stuff.

Thanks for any help,

- keantoken
Posted on 2008-08-23 06:04:18 by keantoken
As the resident game-oriented type without a straight jacket, I commend you, and I will support you and answer your stupid shop questions without hesitation :)
Posted on 2008-08-23 11:15:20 by Homer
As the resident game-oriented type without a straight jacket, I commend you, and I will support you and answer your stupid shop questions without hesitation


Thank you.

It spits out some kind of error during compile about how size?mc is not defined. It doesn't do this for minipad.asm (in the examples directory of FASM), even though I haven't found anything in minipad.asm that would point me to my problem (I'm comparing them side-by side so as to have direction when something wonks out). The compiler output gives me the line number in another include file having to do with the menu function but I sure can't decode it. Could it be that I need to state a variable for this? If so then I haven't found any documentation on MSDN or the ancient win32.hlp file, and no variables like this are stated in minipad.asm.

About shop questions:

1: I'm guessing that almost any number work in windows will be with unsigned integers, unless it has to do with hardware DAC/sound/graphics/algorithms.

2: Is there any way to manually flip the FPU register to do rounding correctly for sound programs too stupid to do it themselves?

Thank you for your answers,

- keantoken
Posted on 2008-08-23 14:46:19 by keantoken
1. Yes
2. No (caveat, you can hook stuff to work around it)

I dont use fasm, but if you post your binary I'll trace it and tell you what and where the problem is.
I'm doing most of my dev work using ObjAsm32, a macro based buildtime environment for masm... something half way between c++ and asm.

I don't actually like masm at all, and you can expect we'll support other assemblers soon via a preprocessor and/or compiler.
Posted on 2008-09-04 22:58:42 by Homer
2) only by manually doing something like
.data
f_05 real4 0.5
.code
fld in_value
fadd f_05
fistp out_value

I just woke up, I don't remember which rounding mode the above needs; maybe just the default.


[ I suspect/recall fasm doesn't have (powerful) macros ] For sane gamedev in asm, I don't see how I'll cope without macros. I even had to make a macro-preprocessor for my non-x86 commercial games, to keep my sanity. Still, x86 has the easiest ISA, so it's possible to get top-notch results quickly even without macros.

Btw, I remember you - at least your interesting nick :)
Posted on 2008-09-05 02:15:17 by Ultrano
Those of you with a good memory might remember me on this forum about a year ago saying something about ASM programming and a game called FlopNinja that I wanted to program as a standalone bootable application.


And the fact that you are very young, and you write quite well (and quite much sometimes  :) )
And something about a cool turtle, too :)

good luck in your programming journey!

Posted on 2008-09-24 03:04:40 by HeLLoWorld